Spring Boot get fields between two dates - spring

I have this DTO in Spring Boot that reference a collection on MongoDB.
#Document(collection = "his")
#AllArgsConstructor
#Getter
#Setter
public class His{
#Id
private String internalId;
private String person;
private String type;
private Date date;
}
And i want to find all objects that the date is between two dates. I already have this (Only with 2 months of difference):
#Override
public ResponseEntity<List<His>> getHisByDate(String dateTo, String dateFrom) {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Period diff = Period.between(LocalDate.parse(dateFrom), LocalDate.parse(dateTo));
if(diff.getYears() == 0 && diff.getMonths() <= 2 && diff.getMonths() >= -2) {
// Here the query
} else {
//Throw Error
}
return null;
}
How i do that with Query?
SOLUTION:
#Override
public ResponseEntity<List<His>> getPagosByFechaPago(String dateTo, String dateFrom) {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date dateHasta = null, dateDesde = null;
try {
dateHasta = formatter.parse(dateTo);
dateDesde = formatter.parse(dateFrom);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Period diff = Period.between(LocalDate.parse(dateFrom), LocalDate.parse(dateTo));
if(diff.getYears() == 0 && diff.getMonths() <= 2 && diff.getMonths() >= -2) {
Query query = new Query();
query.addCriteria(Criteria.where("date").gte(dateHasta).lt(dateDesde));
List<His> response = mongoTemplate.find(query, His.class);
log.info(response.toString());
return new ResponseEntity<>(response, HttpStatus.OK);
} else {
return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
}
}

Try something like that
public interface HisRepository extends MongoRepository<His, String> {
#Query("{ date: { $gte: ?0, $lte: ?1 } }")
List<His> findObjects(Date dateFrom, Date dateTo);
List<His> findAllByDateGreaterThanEqualAndDateLessThanEqual(Date dateFrom, Date dateTo);
}
Please note to the condition of your boundaries: $gte or $gt, $lte or $lt.
https://docs.mongodb.com/manual/reference/operator/query-comparison/

Related

How do I insert values of elements that are part of the EmbeddedId in JPA?

I have a case where I need to execute an insert statement via createNativeQuery. I have an entity list I'm looping through in order to set the properties accordingly from another bean class, and then persist that data to the oracle database.
The problem I am facing is persisting the data that is part of the embeddedId (item, loc, weekstart, type, forecastId, insertTS). I need to persist that data for the new records to be inserted into the database. When I try to set the values from the POJO bean to my set method for the properties of my entity bean, nothing happens. Below is my code for setting the values of the properties from the POJO bean to my entity bean, along with my persistence method and the insert query being executed:
Validation class where validation occurs beforehand (missing to get the point) that includes the setting of my entity properties from the POJO bean:
List <InsertPromoData> insertPromos = new ArrayList<InsertPromoData>();
promo.forEach(record -> {
if (record.getErrorList().size() == 0) {
rowsSuccessful++;
Util.writeSuccessToFile(templateCd, successFile, record, successFields);
try {
InsertPromoData insertData = new InsertPromoData();
insertData.getId().setItem(record.getItem());
insertData.getId().setLoc(record.getLoc());
insertData.getId().setWeekStart(record.getWeek_Start_Date());
insertData.setNumberOfWeeks(record.getNumber_Of_Weeks());
insertData.getId().setType(record.getType());
insertData.getId().setForecastId(record.getForecast_ID());
insertData.setQty(record.getUnits());
insertPromos.add(insertData);
}
catch (Exception e) {
logger.error("Error with setting insertPromolist from promo list values and the error is " + e.getMessage());
}
}
else {
if (rowsFailure == 0) {
Util.writeHeaderToFile(templateCd, errorFile);
}
rowsFailure++;
Util.writeErrorToFile(templateCd, errorFile, record, record.getErrorList());
}
});
errorFile.close();
successFile.close();
OracleImpl.insertPromoData(insertPromos);
POJO bean (promo is the variable representing this list of beans in validation class above):
public class PromoBean extends ErrorListBean
{
public String Item;
public String Loc;
public String Week_Start_Date;
public String Units;
public String Forecast_ID;
public String Type;
public String Number_Of_Weeks;
public String getItem() {
return Item;
}
public void setItem(String item) {
Item = item;
}
public String getLoc() {
return Loc;
}
public void setLoc(String loc) {
Loc = loc;
}
public String getWeek_Start_Date() {
return Week_Start_Date;
}
public void setWeek_Start_Date(String week_Start_Date) {
Week_Start_Date = week_Start_Date;
}
public String getNumber_Of_Weeks() {
return Number_Of_Weeks;
}
public void setNumber_Of_Weeks(String number_Of_Weeks) {
Number_Of_Weeks = number_Of_Weeks;
}
public String getType() {
return Type;
}
public void setType(String type) {
Type = type;
}
public String getForecast_ID() {
return Forecast_ID;
}
public void setForecast_ID(String forecast_ID) {
Forecast_ID = forecast_ID;
}
public String getUnits() {
return Units;
}
public void setUnits(String units) {
Units = units;
}
}
Embeddable class representing the composite primary key of the table:
#Embeddable
public class PromoID implements Serializable {
#Column(name = "ITEM")
private String item;
#Column(name = "LOC")
private String loc;
#Column(name = "WK_START")
private String weekStart;
#Column(name = "TYPE")
private String type;
#Column(name = "FCSTID")
private String forecastId;
#Column(name = "U_TIMESTAMP")
private String insertTS;
public PromoID() {
}
public PromoID (String item, String loc, String weekStart, String type, String forecastId, String insertTS) {
this.item = item;
this.loc = loc;
this.weekStart = weekStart;
this.type = type;
this.forecastId = forecastId;
this.insertTS = insertTS;
}
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
public String getWeekStart() {
return weekStart;
}
public void setWeekStart(String weekStart) {
this.weekStart = weekStart;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getForecastId() {
return forecastId;
}
public void setForecastId(String forecastId) {
this.forecastId = forecastId;
}
public String getInsertTS() {
return insertTS;
}
public void setInsertTS(String insertTS) {
this.insertTS = insertTS;
}
//hashcode and equals methods
Persistence Bean:
#Entity
#Table(name = "U_USER_PROMO")
public class InsertPromoData {
#EmbeddedId
private PromoID id;
#Column(name="NUMBER_OF_WEEKS")
String numberOfWeeks;
#Column(name="QTY")
String qty;
#Id
#AttributeOverrides(
{
#AttributeOverride(name = "item",column = #Column(name="ITEM")),
#AttributeOverride(name = "loc", column = #Column(name="LOC")),
#AttributeOverride(name = "weekStart", column = #Column(name="WK_START")),
#AttributeOverride(name = "type", column = #Column(name="TYPE")),
#AttributeOverride(name = "forecastId", column = #Column(name="FCSTID"))
}
)
public PromoID getId() {
return id;
}
public void setId(PromoID id) {
this.id = id;
}
public String getNumberOfWeeks() {
return numberOfWeeks;
}
public void setNumberOfWeeks(String numberOfWeeks) {
this.numberOfWeeks = numberOfWeeks;
}
public String getQty() {
return qty;
}
public void setQty(String qty) {
this.qty = qty;
}
}
DAO class method to execute the update (entitymanagerfactory emf already initialized):
public static void insertPromoData(List<InsertPromoData> insertData) {
logger.debug("Execution of method insertPromoData in Dao started");
System.out.println("Size of the insertData list is " + insertData.size());
EntityManager em = emf.createEntityManager();
try {
em.getTransaction().begin();
System.out.println("Beginning transaction for insertPromoData");
Query query = em.createNativeQuery(env.getProperty("insertPromoUploadData"));
for (InsertPromoData promoData : insertData) {
query.setParameter("item", promoData.getId().getItem());
query.setParameter("location", promoData.getId().getLoc());
query.setParameter("wkStart", promoData.getId().getWeekStart());
query.setParameter("numberOfWeeks", promoData.getNumberOfWeeks());
query.setParameter("type", promoData.getId().getType());
query.setParameter("fcstId", promoData.getId().getForecastId());
query.setParameter("quantity", promoData.getQty());
query.executeUpdate();
}
em.getTransaction().commit();
}
catch(Exception e) {
logger.error("Exception in beginning transaction");
e.printStackTrace();
}
finally {
em.clear();
em.close();
}
logger.debug("Execution of method insertPromoData in Dao ended");
}
Query in properties file:
insertPromoUploadData = INSERT INTO {h-schema}U_USER_PROMO (ITEM, LOC, WK_START, NUMBER_OF_WEEKS, TYPE, FCSTID, QTY, U_TIMESTAMP) VALUES (:item, :location, TO_DATE(:wkStart,'MM DD YYYY'), :numberOfWeeks, :type, :fcstId, :quantity, SYSDATE)
My list size from my DAO class is returning as 0 once I begin the transaction and not sure why it is empty. Is there a reason that it is empty? I'm trying to persist each of the fields to the database (including the composite key fields) via insert query. Any help appreciated.
After looking into this for hours, I finally came to the conclusion that the simplest way to executeUpdate() without running into issues due to my current #EmbeddedId/#Embeddable logic was to change it to use #IdClass for my composite PK class, and annotate the fields from the PK in my entity with #Id. This allowed my data to be persisted to the database. Another slight difference was adding the insertTS in my entity class and annotating with #Id and generating getters/setters. This was necessary for JPA to recognize all the properties being referenced that I am wanting to persist, though I am persisting insertTS using SYSDATE function from the oracle DB instead of utilizing the get/set methods and setting to the current time from the java side.
I am sure there is a way to use #EmbeddedId/#Embeddable logic and be able to persist the fields that are part of the EmbeddedId, however, this I found to be a more simplistic way of doing it without further complexity in the code.

PayPal REST API returns INVALID_CURRENCY_AMOUNT_FORMAT

response-code: 400 details: name: VALIDATION_ERROR message: Invalid request - see details details: [{
"field": "transactions.amount",
"issue": "Cannot construct instance of com.paypal.platform.payments.model.rest.common.Amount, >problem: INVALID_CURRENCY_AMOUNT_FORMAT"
}] debug-id: 86ad5783892c3 information-link: https://developer.paypal.com/docs/api/payments/#errors
package com.spring.soap.api;
#Configuration
public class PaypalConfig {
#Value("${paypal.client.id}")
private String clientId;
#Value("${paypal.client.secret}")
private String clientSecret;
#Value("${paypal.mode}")
private String mode;
#Bean
public Map<String,String> paypalSdkConfig(){
Map<String,String> configMap= new HashMap<>();
configMap.put("mode",mode);
return configMap;
}
#Bean
public OAuthTokenCredential oAuthTokenCredential() {
return new OAuthTokenCredential(clientId,clientSecret,paypalSdkConfig());
}
#Bean
public APIContext apiContext() throws PayPalRESTException {
APIContext context = new APIContext(oAuthTokenCredential().getAccessToken());
context.setConfigurationMap(paypalSdkConfig());
return context;
}
}
{
#Autowired
PaypalService service;
public static final String SUCCESS_URL = "pay/success";
public static final String CANCEL_URL = "pay/cancel";
#GetMapping("/")
public String home() {
return "home";
}
#PostMapping("/pay")
public String payment(#ModelAttribute("order") Order order) {
try {
Payment payment = service.createPayment(order.getPrice(), order.getCurrency(), order.getMethod(),
order.getIntent(), order.getDescription(), "http://localhost:9090/" + CANCEL_URL,
"http://localhost:9090/" + SUCCESS_URL);
for(Links link:payment.getLinks()) {
if(link.getRel().equals("approval_url")) {
return "redirect:"+link.getHref();
}
}
} catch (PayPalRESTException e) {
e.printStackTrace();
}
return "redirect:/";
}
#GetMapping(value = CANCEL_URL)
public String cancelPay() {
return "cancel";
}
#GetMapping(value = SUCCESS_URL)
public String successPay(#RequestParam("paymentId") String paymentId, #RequestParam("PayerID") String payerId) {
try {
Payment payment = service.executePayment(paymentId, payerId);
System.out.println(payment.toJSON());
if (payment.getState().equals("approved")) {
return "success";
}
} catch (PayPalRESTException e) {
System.out.println(e.getMessage());
}
return "redirect:/";
}
}
{
#Autowired
private APIContext apiContext;
public Payment createPayment(
Double total,
String currency,
String method,
String intent,
String description,
String cancelUrl,
String successUrl) throws PayPalRESTException{
Amount amount = new Amount();
amount.setCurrency(currency);
total = new BigDecimal(total).setScale(2, RoundingMode.HALF_UP).doubleValue();
amount.setTotal(String.format("%.2f", total));
Transaction transaction = new Transaction();
transaction.setDescription(description);
transaction.setAmount(amount);
List<Transaction> transactions = new ArrayList<>();
transactions.add(transaction);
Payer payer = new Payer();
payer.setPaymentMethod(method);
Payment payment = new Payment();
payment.setIntent(intent);
payment.setPayer(payer);
payment.setTransactions(transactions);
RedirectUrls redirectUrls = new RedirectUrls();
redirectUrls.setCancelUrl(cancelUrl);
redirectUrls.setReturnUrl(successUrl);
payment.setRedirectUrls(redirectUrls);
return payment.create(apiContext);
}
public Payment executePayment(String paymentId, String payerId) throws PayPalRESTException{
Payment payment = new Payment();
payment.setId(paymentId);
PaymentExecution paymentExecute = new PaymentExecution();
paymentExecute.setPayerId(payerId);
return payment.execute(apiContext, paymentExecute);
}
}
It would appear your locale is formatting decimals with a comma (,) as the decimal separator.
The PayPal API exclusively accepts numbers with a period (.) as the decimal separator
Take this line:
amount.setTotal(String.format("%.2f", total));
Change %.2f to %.3f. The final code should look like:
amount.setTotal(String.format("%.3f", total));
In my case I was sending the SubTotal on Details with a NON rounded value:
141.750
So I just round the value like this:
details.setSubtotal(subTotal.setScale(2, BigDecimal.ROUND_HALF_EVEN).toString());
(In other words)
141.75

Mapstruct mapping with condition and nullValuePropertyMappingStrategy

I apologize if the title is not clear, let me make it clear by giving sample codes:
UpdateProfileDto
public class UpdateProfileDto {
#NotEmpty
private String firstName;
#NotEmpty
private String lastName;
#Size(max = 20)
private String currentPassword;
#Size(max = 20)
private String newPassword;
#Size(max = 20)
private String confirmNewPassword;
// getters and setters
}
EncodedMapping
#Qualifier
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.CLASS)
public #interface EncodedMapping {
}
PasswordEncoderMapper
public class PasswordEncoderMapper {
protected final PasswordEncoder passwordEncoder;
public PasswordEncoderMapper(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
#EncodedMapping
public String encode(String value) {
return passwordEncoder.encode(value);
}
}
UserMapper
#Mapper(config = MapperConfig.class, componentModel = "spring", uses = PasswordEncoderMapper.class)
public interface UserMapper {
#Mappings({
#Mapping(target = "firstName", source = "firstName"),
#Mapping(target = "lastName", source = "lastName"),
#Mapping(target = "fullName", expression = "java(user.getFirstName() + \" \" + user.getLastName())"),
#Mapping(target = "password",
source = "newPassword",
nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE,
qualifiedBy = EncodedMapping.class)
})
void updateUserFromDto(UpdateUserProfileDto updateUserProfileDto, #MappingTarget User user);
}
Generated UserMapperImpl
#Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2020-03-11T13:51:34+0800",
comments = "version: 1.3.0.Final, compiler: javac, environment: Java 1.8.0_231 (Oracle Corporation)"
)
#Component
public class UserMapperImpl implements UserMapper {
#Autowired
private PasswordEncoderMapper passwordEncoderMapper;
#Override
public void updateUserFromDto(UpdateUserProfileDto updateUserProfileDto, User user) {
if ( updateUserProfileDto == null ) {
return;
}
if ( updateUserProfileDto.getFirstName() != null ) {
user.setFirstName( updateUserProfileDto.getFirstName() );
}
else {
user.setFirstName( null );
}
if ( updateUserProfileDto.getLastName() != null ) {
user.setLastName( updateUserProfileDto.getLastName() );
}
else {
user.setLastName( null );
}
if ( updateUserProfileDto.getNewPassword() != null ) {
user.setPassword( passwordEncoderMapper.encode( updateUserProfileDto.getNewPassword() ) );
}
user.setFullName( user.getFirstName() + " " + user.getLastName() );
}
}
From the generated UserMapperImpl, I would like to check not only if newPassword has value... but to check currentPassword and newPassword have values and proceed with user.setPassword().
I mean something like this:
...
if ( updateUserProfileDto.getCurrentPassword() != null && updateUserProfileDto.getNewPassword() != null ) {
user.setPassword( passwordEncoderMapper.encode( updateUserProfileDto.getNewPassword() ) );
}
...
Problem
How could I change my mapper interface UserMapper so that i will check both currentPassword and newPassword before it will set the target user.password and will still use PasswordEncoderMapper.encode(password)?
If I try to use expression instead of source and check both currentPassword and newPassword if both have values and then set user.password to newPassword. Otherwise, it will not do anything to user.passwordusing NullValuePropertyMappingStrategy... but it seems it is not allowede to mix expression and NullValuePropertyMappingStrategy.
Thanks!
I would start with following approach
#Mapper(config = MapperConfig.class, componentModel = "spring")
public abstract class UserMapper { // using class instead of interface to be able to inject beans
#Autowired
private PasswordEncoderMapper passwordEncoderMapper;
#Mappings({
// your non-password mappings
})
void updateUserFromDto(UpdateUserProfileDto updateUserProfileDto, #MappingTarget User user);
#AfterMapping
void setPassword(UpdateUserProfileDto updateUserProfileDto, #MappingTarget User user) {
if (updateUserProfileDto.getCurrentPassword() != null && updateUserProfileDto.getNewPassword() != null) {
user.setPassword(passwordEncoderMapper.encode( updateUserProfileDto.getNewPassword()));
}
}
}

hibernate/Spring/Jpa #oneToMany cascade update

I'm trying to add in the decorator cascade = CascadeType.ALL on the field one to many of my version modele in spring in order to update every hyper parameter when i update my version.Like you can see below.
#Entity
#Table(name = "version")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Version implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
#Column(name = "num", nullable = false)
private Integer num;
#Column(name = "creation_date")
private ZonedDateTime creationDate;
#Column(name = "execution_date")
private ZonedDateTime executionDate;
#Column(name = "weights_uri")
private String weightsURI;
#OneToMany(mappedBy = "version", fetch = FetchType.EAGER, orphanRemoval = true)
#JsonIgnoreProperties({"version", "metricsType"})
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<ResultExecution> resultExecutions = new HashSet<>();
#OneToMany(mappedBy = "version", fetch = FetchType.EAGER, orphanRemoval = true, cascade = CascadeType.ALL)
#JsonIgnoreProperties({"version"})
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<HyperParameter> hyperParameters = new HashSet<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getNum() {
return num;
}
public Version num(Integer num) {
this.num = num;
return this;
}
public void setNum(Integer num) {
this.num = num;
}
public ZonedDateTime getCreationDate() {
return creationDate;
}
public Version creationDate(ZonedDateTime creationDate) {
this.creationDate = creationDate;
return this;
}
public void setCreationDate(ZonedDateTime creationDate) {
this.creationDate = creationDate;
}
public ZonedDateTime getExecutionDate() {
return executionDate;
}
public Version executionDate(ZonedDateTime executionDate) {
this.executionDate = executionDate;
return this;
}
public void setExecutionDate(ZonedDateTime executionDate) {
this.executionDate = executionDate;
}
public String getWeightsURI() {
return weightsURI;
}
public Version weightsURI(String weightsURI) {
this.weightsURI = weightsURI;
return this;
}
public void setWeightsURI(String weightsURI) {
this.weightsURI = weightsURI;
}
public Set<ResultExecution> getResultExecutions() {
return resultExecutions;
}
public Version resultExecutions(Set<ResultExecution> resultExecutions) {
this.resultExecutions = resultExecutions;
return this;
}
public Version addResultExecution(ResultExecution resultExecution) {
this.resultExecutions.add(resultExecution);
resultExecution.setVersion(this);
return this;
}
public Version removeResultExecution(ResultExecution resultExecution) {
this.resultExecutions.remove(resultExecution);
resultExecution.setVersion(null);
return this;
}
public void setResultExecutions(Set<ResultExecution> resultExecutions) {
this.resultExecutions = resultExecutions;
}
public Set<HyperParameter> getHyperParameters() {
return hyperParameters;
}
public Version hyperParameters(Set<HyperParameter> hyperParameters) {
this.hyperParameters = hyperParameters;
return this;
}
public Version addHyperParameter(HyperParameter hyperParameter) {
this.hyperParameters.add(hyperParameter);
hyperParameter.setVersion(this);
return this;
}
public Version removeHyperParameter(HyperParameter hyperParameter) {
this.hyperParameters.remove(hyperParameter);
hyperParameter.setVersion(null);
return this;
}
public void setHyperParameters(Set<HyperParameter> hyperParameters) {
this.hyperParameters = hyperParameters;
}
public Set<Data> getData() {
return data;
}
public Version data(Set<Data> data) {
this.data = data;
return this;
}
public Version addData(Data data) {
this.data.add(data);
data.getVersions().add(this);
return this;
}
public Version removeData(Data data) {
this.data.remove(data);
data.getVersions().remove(this);
return this;
}
public void setData(Set<Data> data) {
this.data = data;
}
public ModelConfiguration getModelConfiguration() {
return modelConfiguration;
}
public Version modelConfiguration(ModelConfiguration modelConfiguration) {
this.modelConfiguration = modelConfiguration;
return this;
}
public void setModelConfiguration(ModelConfiguration modelConfiguration) {
this.modelConfiguration = modelConfiguration;
}
// jhipster-needle-entity-add-getters-setters - Jhipster will add getters and setters here, do not remove
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Version version = (Version) o;
if (version.getId() == null || getId() == null) {
return false;
}
return Objects.equals(getId(), version.getId());
}
#Override
public int hashCode() {
return Objects.hashCode(getId());
}
#Override
public String toString() {
return "Version{" +
"id=" + getId() +
", num='" + getNum() + "'" +
", creationDate='" + getCreationDate() + "'" +
", executionDate='" + getExecutionDate() + "'" +
", weightsURI='" + getWeightsURI() + "'" +
"}";
}
}
My hyperParameter model looks like this :
#Entity
#Table(name = "hyper_parameter")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class HyperParameter implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
#Column(name = "parameter_value", nullable = false)
private String parameterValue;
#ManyToOne(optional = false)
#NotNull
#JsonIgnoreProperties({"resultExecutions", "hyperParameters", "data", "modelConfiguration"})
private Version version;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getParameterValue() {
return parameterValue;
}
public HyperParameter parameterValue(String parameterValue) {
this.parameterValue = parameterValue;
return this;
}
public void setParameterValue(String parameterValue) {
this.parameterValue = parameterValue;
}
public Version getVersion() {
return version;
}
public HyperParameter version(Version version) {
this.version = version;
return this;
}
public void setVersion(Version version) {
this.version = version;
}
public HyperParameterType getHyperParameterType() {
return hyperParameterType;
}
public HyperParameter hyperParameterType(HyperParameterType hyperParameterType) {
this.hyperParameterType = hyperParameterType;
return this;
}
public void setHyperParameterType(HyperParameterType hyperParameterType) {
this.hyperParameterType = hyperParameterType;
}
// jhipster-needle-entity-add-getters-setters - Jhipster will add getters and setters here, do not remove
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
HyperParameter hyperParameter = (HyperParameter) o;
if (hyperParameter.getId() == null || getId() == null) {
return false;
}
return Objects.equals(getId(), hyperParameter.getId());
}
#Override
public int hashCode() {
return Objects.hashCode(getId());
}
#Override
public String toString() {
return "HyperParameter{" +
"id=" + getId() +
", parameterValue='" + getParameterValue() + "'" +
"}";
}
}
I update a json and try a put with it .I change the value of the field parametervalue from 2 to 3 .
{
"id": 1,
"num": 1,
"creationDate": "2017-05-11T00:00:00+02:00",
"executionDate": null,
"weightsURI": "tests/scripts/sequential/weights/weights_le_net_5.h5py",
"resultExecutions": [
{
"id": 1,
"metricValues": "",
"executionType": "TRAIN",
"numPrediction": null
},
{
"id": 2,
"metricValues": "",
"executionType": "TRAIN",
"numPrediction": null
}
],
"hyperParameters": [
{
"id": 1,
"parameterValue": "2",
"hyperParameterType": {
"id": 1,
"name": "epochs",
"parameterType": "INTEGER",
"parameterDefaultValue": "0",
"isRequired": true
}
},
{
"id": 2,
"parameterValue": "32",
"hyperParameterType": {
"id": 2,
"name": "batch_size",
"parameterType": "INTEGER",
"parameterDefaultValue": "32",
"isRequired": true
}
}
],
"modelConfiguration": {
"id": 1,
"name": "Modele LeNet5",
"creationDate": "2017-05-11T00:00:00+02:00",
"updateDate": "2017-05-11T00:00:00+02:00",
"saveURI": "tests/scripts/sequential/models/le_net_5.json"
}
}
But when i do i got a 500 internal serveur error and stack trace like the one bellow about a null constraint violation.
<!-- What do you expect the result to be? -->
<!-- What is the actual result you get? (Please include any errors.) -->
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:526)
[1:59]
t org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:75)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:71)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
... 153 common frames omitted
Caused by: javax.validation.ConstraintViolationException: Validation failed for classes [com.saagie.picsaagie2017_frontend.domain.HyperParameter] during update time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='can not be null ', propertyPath=version, rootBeanClass=class com.saagie.picsaagie2017_frontend.domain.HyperParameter, messageTemplate='{javax.validation.constraints.NotNull.message}'}
]
How can i update my hyperParameters when i update my version whitout getting this error.
Use the #PreUpdate and #PrePersist callbacks in the HyperParameter class like so:
#PreUpdate
#PrePersist
public void setChildObjects() {
if (getVersions() != null)
{
for (Version version : getVersions())
{
version.setHyperParameters (this);
}
}
}
Refer to this for more information : http://docs.jboss.org/hibernate/core/3.3/reference/en/html/tutorial.html#tutorial-associations-usingbidir
Both solution actually work i had a second error because of what is discussed in that topic : Spring data rest one to many cascade all . I just had to add #JsonManagedReference and #JsonBackReference because i had marshalling problem on the reference of version when i tried to update my HyperParameters in cascade.
You just have validation error. You try to put interpolatedMessage with null value. Ok but first remove #NotNull annotation on this field.

How to Use Mongo Pojos in Bulk Upsert

Hi i have a list of Mongo Pojo I want to use upsert .I don't know how to use My pojo's .
#Test
public void testAgentDataStorage() {
AgentDataStorage a = new AgentDataStorage(124l);
DBCollection collection = mongoTemplate.getDb().getCollection("agent_data_storage");
BulkWriteOperation bulkWriteOperation = collection.initializeUnorderedBulkOperation();
BulkWriteRequestBuilder bulkWriteRequestBuilder = bulkWriteOperation.find((DBObject) a);
BulkUpdateRequestBuilder updateReq = bulkWriteRequestBuilder.upsert();
a.getDataPoints().put("TOTAL_INCENTIVE_EARNINGS" , 13);
updateReq.replaceOne((DBObject) a);
BulkWriteResult result = bulkWriteOperation.execute();
}
Here AgentDataStorage is my pojo and this code is giving error
AgentDataStorage cannot be cast to com.mongodb.DBObject .
Below is my AgentDataStorage
#CompoundIndex(name = "account_date_idx", def = "{'account' : 1, 'date' : 1}", unique = true)
#Document(collection = "agent_data_storage")
public class AgentDataStorage extends MongoKeyedEntity<String> implements Serializable {
public static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
#Field
private Long account;
#Field()
private String date;
#Field
private Map<String, Integer> dataPoints = new HashMap<>();
public AgentDataStorage(Long account) {
this.account = account;
this.date = dateFormat.format(new Date());
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0);
}
}
public AgentDataStorage(String account) {
this.account = Long.valueOf(account);
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0);
}
}
public AgentDataStorage(Long account, Date date) {
this.account = account;
this.date = dateFormat.format(date);
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0);
}
}
public AgentDataStorage(Long account, Date date, Map<String, Integer> dataPoints) {
this.account = account;
this.date = dateFormat.format(date);
this.dataPoints = dataPoints;
}
public AgentDataStorage(String account, Date date) {
this.account = Long.valueOf(account);
this.date = dateFormat.format(date);
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0);
}
}
public AgentDataStorage(String account, String date) {
this.account = Long.valueOf(account);
this.date = date;
for (AgentDataPoints dataPoint : EnumSet.allOf(AgentDataPoints.class)) {
this.dataPoints.put(dataPoint.toString(), 0);
}
}
public Long getAccount() {
return account;
}
public void setAccount(Long account) {
this.account = account;
}
public Date getDate() throws ParseException {
return dateFormat.parse(this.date);
}
public void setDate(Date date) {
this.date = dateFormat.format(date);
}
public Map<String, Integer> getDataPoints() {
return dataPoints;
}
public void setDataPoints(Map<String, Integer> dataPoints) {
this.dataPoints = dataPoints;
}
public void updateDataPoint(AgentDataPoints agentDataPoints, Integer value) {
this.dataPoints.put(String.valueOf(agentDataPoints), value);
}
Mongo Java Driver doesn't have support for complex types and it looks like your pojos are annotated with spring mongo db annotation.
You've couple of options here MongoTemplate and MongoRepository.
MongoTemplate: http://docs.spring.io/spring-data/data-mongo/docs/1.10.0.M1/reference/html/#mongo-template
MongoRepository: http://docs.spring.io/spring-data/data-mongo/docs/1.10.0.M1/reference/html/#mongo.repositories

Resources