TransactionSystemException when #Scheduled is used - spring

When I want to use #Scheduled, it throws org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
When I tried to use noRollbackFor=TransactionSystemException - it does not help either...
I even tried to use propagation=NEVER and then the code does not work,because it needs to be transactional. Iam getting those documents ok, but I cannot do blockDocument(document).
How to make it work?
Thank you in advance
#Component
public class ScheduleService {
#Autowired
private DocumentService documentService;
#Scheduled(cron = "0 33 13 * * ?")
public void blockPassedDocuments() {
List<Document> passedDocuments = documentService.getAllPassedDocuments();
if (passedDocuments != null) {
System.out.println("blocked docs "+ passedDocuments.size());
passedDocuments.forEach(document -> documentService.blockDocument(document));
}
}
}
#Service
#Transactional
public class DocumentService {
#Autowired
private DocumentRepository documentRepository;
#Autowired
private UserService userService;
#Autowired
private EmailService emailService;
#Transactional(noRollbackFor = TransactionSystemException.class)
public void blockDocument(Document document){
documentRepository.blockDocument(document);
}
// repository
#Override
public void blockDocument(Document document) {
DocumentState documentState = getDocumentState(3);
document.setDocumentState(documentState);
entityManager.merge(document);
}
#Entity
#Table(name = "document_state")
public class DocumentState {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#NotBlank(message = "State is mandatory")
#Size(min=1, max=60)
#Column(length = 60)
private String state;
#JsonIgnore
#OneToMany(mappedBy = "documentState", cascade= CascadeType.ALL)
private List<Document> documents;
public DocumentState(){
}
#Entity
public class Document {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column(unique = true, length = 60, nullable = false)
#NotBlank(message = "Name is mandatory")
private String name;
#NotBlank(message = "Title is mandatory")
#Size(min = 3, max = 15)
#Column(length = 15, nullable = false)
private String title;
#NotBlank(message = "Description is mandatory")
#Size(min = 3, max = 255)
#Column(length = 255, nullable = false)
private String description;
#ManyToOne
#JoinColumn(name = "document_state_id", nullable = false)
private DocumentState documentState;
#JsonIgnore
#Column(name = "resource_path", length = 255, nullable = false)
private String resourcePath;
#Column(name = "upload_datetime", columnDefinition = "DATETIME", nullable = false)
#Temporal(TemporalType.TIMESTAMP)
#NotNull(message = "UploadDateTime is mandatory")
private Date uploadDatetime;
#Column(name = "approval_end_time", columnDefinition = "DATETIME", nullable = false)
#Temporal(TemporalType.TIMESTAMP)
#NotNull(message = "Approval end time is mandatory")
private Date approvalEndTime;
#Column(name = "active_start_time", columnDefinition = "DATETIME", nullable = false)
#Temporal(TemporalType.TIMESTAMP)
#NotNull(message = "Active start time is mandatory")
private Date activeStartTime;
#Column(name = "active_end_time", columnDefinition = "DATETIME", nullable = false)
#Temporal(TemporalType.TIMESTAMP)
#NotNull(message = "Active end time is mandatory")
private Date activeEndTime;
#OneToMany(mappedBy = "document", cascade= CascadeType.ALL, orphanRemoval = true)
private Set<UsersDocuments> documentsForUsers = new HashSet<>();
#ManyToOne
#JoinColumn(name="user_id")
private User user;
public DocumentState getDocumentState() {
return documentState;
}
EDIT STACK:
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:541) ~[spring-orm-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:746) ~[spring-tx-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:714) ~[spring-tx-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:534) ~[spring-tx-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:305) ~[spring-tx-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) ~[spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at com.patrikmaryska.bc_prace.bc_prace.service.ScheduleService$$EnhancerBySpringCGLIB$$68ed607b.blockPassedDocuments(<generated>) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:567) ~[na:na]
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:93) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) ~[na:na]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at java.base/java.lang.Thread.run(Thread.java:835) ~[na:na]

Add the #Transactional annotation on blockPassedDocuments method.

Add the #Transactional annotation on ScheduleService class.

Related

Model mapper Converter failed to convert Object to java.lang.Integer with java.lang.NullPointerException

perhaps someone can give me an insite. Ok i have Purchase Entity with nested Transaction set of Entities. What i'm trying to do is convert additional DTO property Integer paymentStatus using custom method but getting NullPointerException for ModelMapper Converter
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
#Entity
#Table(name = "purchase")
public class Purchase {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "purchase_id", nullable = false)
private Integer purchaseId;
#Column(name = "purchase_total_cost")
private Double purchaseTotalCost;
#Column(name = "purchase_company_id", nullable = false)
private Integer purchaseCompanyId;
#Column(name = "purchase_user_id", nullable = false)
private Integer purchaseUserId;
#Column(name = "purchase_stock_id", nullable = false)
private Integer purchaseStockId;
#Column(name = "purchase_supplier_contact_id")
private Integer purchaseSupplierContactId;
#Column(name = "purchase_supplier_id")
private Integer purchaseSupplierId;
#Column(name = "purchase_inventory_id")
private Integer purchaseInventoryId;
#Column(name = "purchase_date")
private LocalDateTime purchaseDate;
#Column(name = "date_created")
#CreationTimestamp
public LocalDateTime dateCreated;
#Column(name = "date_updated")
#UpdateTimestamp
public LocalDateTime dateUpdated;
#ToString.Exclude
#EqualsAndHashCode.Exclude
#ManyToOne
#JoinColumn(name = "purchase_user_id", referencedColumnName = "user_id", insertable = false, updatable = false)
private User purchaseUser;
#ToString.Exclude
#EqualsAndHashCode.Exclude
#ManyToOne
#JoinColumn(name = "purchase_stock_id", referencedColumnName = "stock_id", insertable = false, updatable = false)
private Stock purchaseStock;
#ToString.Exclude
#EqualsAndHashCode.Exclude
#ManyToOne
#JoinColumn(name = "purchase_supplier_id", referencedColumnName = "supplier_id", insertable = false, updatable = false)
private Supplier purchaseSupplier;
#ToString.Exclude
#EqualsAndHashCode.Exclude
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "purchase_supplier_contact_id", referencedColumnName = "contact_id", insertable = false, updatable = false)
private SupplierContact purchaseSupplierContact;
#ToString.Exclude
#EqualsAndHashCode.Exclude
#ManyToOne
#JoinColumn(name = "purchase_company_id", referencedColumnName = "company_id", insertable = false, updatable = false)
private Company purchaseCompany;
#ToString.Exclude
#EqualsAndHashCode.Exclude
#ManyToOne
#JoinColumn(name = "purchase_inventory_id", referencedColumnName = "inventory_id", insertable = false, updatable = false)
private Inventory purchaseInventory;
#ToString.Exclude
#EqualsAndHashCode.Exclude
#OneToMany(fetch = FetchType.LAZY,
mappedBy = "costLogPurchase")
#Cascade({org.hibernate.annotations.CascadeType.MERGE,
org.hibernate.annotations.CascadeType.DELETE,
org.hibernate.annotations.CascadeType.REMOVE
})
private Set<CostLog> purchaseCostLogs;
#ToString.Exclude
#EqualsAndHashCode.Exclude
#OneToMany(fetch = FetchType.LAZY,
cascade = CascadeType.ALL,
mappedBy = "ingredientPurchase")
private Set<PurchaseHasIngredient> purchaseIngredients;
// #ToString.Exclude
#EqualsAndHashCode.Exclude
#OneToMany(fetch = FetchType.EAGER,
cascade = CascadeType.ALL,
mappedBy = "transactionPurchase")
private Set<Transaction> purchaseTransactions;
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
#Entity
#Table(name = "transaction")
public class Transaction {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "transaction_id", nullable = false)
private Integer transactionId;
#Column(name = "transaction_status")
private Byte transactionStatus;
#Column(name = "transaction_amount", nullable = false)
private Double transactionAmount;
#Column(name = "transaction_code", length = 100)
private String transactionCode;
#Column(name = "transaction_payment_point_id")
private Integer transactionPaymentPointId;
#Column(name = "transaction_user_id")
private Integer transactionUserId;
#Column(name = "transaction_order_id")
private Integer transactionOrderId;
#Column(name = "transaction_purchase_id")
private Integer transactionPurchaseId;
#Column(name = "transaction_date")
public LocalDateTime transactionDate;
#Column(name = "date_created")
#CreationTimestamp
public LocalDateTime dateCreated;
#Column(name = "date_updated")
#UpdateTimestamp
public LocalDateTime dateUpdated;
#EqualsAndHashCode.Exclude
#ToString.Exclude
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "transaction_payment_point_id", referencedColumnName = "payment_point_id", insertable = false, updatable = false)
private PaymentPoint transactionPaymentPoint;
#EqualsAndHashCode.Exclude
#ToString.Exclude
#ManyToOne
#JoinColumn(name = "transaction_user_id", referencedColumnName = "user_id", insertable = false, updatable = false)
private User transactionUser;
#EqualsAndHashCode.Exclude
#ToString.Exclude
#ManyToOne
#Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
#JoinColumn(name = "transaction_order_id", referencedColumnName = "order_id", insertable = false, updatable = false)
private Order transactionOrder;
#EqualsAndHashCode.Exclude
#ToString.Exclude
#ManyToOne(fetch = FetchType.EAGER)
#Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
#JoinColumn(name = "transaction_purchase_id", referencedColumnName = "purchase_id", insertable = false, updatable = false)
private Purchase transactionPurchase;
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
public class TransactionDTO implements Serializable {
private static final long serialVersionUID = 1L;
private Integer transactionId;
private Byte transactionStatus;
private Double transactionAmount;
private String transactionCode;
private Integer transactionPaymentPointId;
private String transactionPaymentPointName;
private Integer transactionUserId;
private String transactionUserName;
private Integer transactionOrderId;
private Integer transactionPurchaseId;
public LocalDateTime transactionDate;
public LocalDateTime dateCreated;
public LocalDateTime dateUpdated;
}
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
public class PurchaseDTO {
private static final long serialVersionUID = 1L;
private Integer purchaseId;
private Integer purchaseUserId;
private String purchaseUserName;
private Integer purchaseCompanyId;
private Integer purchaseStockId;
private String purchaseStockName;
private Integer purchaseSupplierId;
private String purchaseSupplierName;
private Integer paymentStatus; // this is additional property
private Integer purchaseInventoryId;
private Double purchaseTotalCost;
private Integer purchaseSupplierContactId;
private LocalDateTime purchaseDate;
private LocalDateTime dateCreated;
private LocalDateTime dateUpdated;
private Set<PurchaseHasIngredientDTO> purchaseIngredients;
private Set<TransactionDTO> purchaseTransactions;
#Configuration
public class ModelMapperConfig {
#Bean
public ModelMapper modelMapper() {
ModelMapper mapper = new ModelMapper();
mapper.getConfiguration().setPreferNestedProperties(false)
.setSkipNullEnabled(true)
.setMatchingStrategy(MatchingStrategies.STANDARD);
mapper.createTypeMap(Purchase.class, PurchaseDTO.class)
.addMappings(purchaseDTOPropertyMapUsingPaymentStatusConverter);
return mapper;
}
PropertyMap<Purchase, PurchaseDTO> purchaseDTOPropertyMapUsingPaymentStatusConverter = new PropertyMap<>() {
#Override
protected void configure() {
using(ctx->mapSpecificFields(source.getPurchaseTransactions(), source.getPurchaseTotalCost())).
map(source, destination.getPaymentStatus());
}
};
public Integer mapSpecificFields(Set<Transaction> set, Double total) {
int b;
if(set==null){
b = 0;
}
double result = 0;
for(Transaction transaction: set) {
double sum = transaction.getTransactionAmount();
sum++;
result = sum/total;
}
if(result==0){
b=0;
}else if (result==1){
b=2;
}else{
b=1;
}
return b;
}
}
#Service
public class PurchaseService extends EntityMapperService<PurchaseDTO, Purchase> implements EntityService<Purchase> {
#PersistenceContext
private EntityManager entityManager;
private final PurchaseRepository repository;
private final PurchaseHasIngredientRepository purchaseIngredientsRepository;
private final ModelMapper mapper;
#Override
public PurchaseDTO toDto(Purchase entity) {
return Objects.isNull(entity)
? null
: mapper.map(entity, PurchaseDTO.class);
}
}
test set up
#SpringBootTest
class PurchaseServiceTest {
#Autowired
private ModelMapper mapper;
#Autowired
private PurchaseService service;
Transaction t1;
Transaction t2;
Set<Transaction> transactions;
TransactionDTO td1;
TransactionDTO td2;
Set<TransactionDTO> transactionDTOS;
Purchase purchase;
PurchaseDTO dto;
#BeforeEach
void setUp() {
t1 = Transaction.builder()
.transactionId(11)
.transactionAmount(12.00)
.transactionPurchaseId(1)
.build();
t2 = Transaction.builder()
.transactionId(12)
.transactionAmount(10.00)
.transactionPurchaseId(1)
.build();
transactions = Sets.newHashSet(t1,t2);
td1 = TransactionDTO.builder()
.transactionPurchaseId(1)
.transactionId(11)
.transactionAmount(12.00)
.build();
td2 = TransactionDTO.builder()
.transactionId(12)
.transactionPurchaseId(1)
.transactionAmount(10.00)
.build();
transactionDTOS = Sets.newHashSet(td1,td2);
purchase = Purchase.builder()
.purchaseId(1)
.purchaseCompanyId(2)
.purchaseUserId(3)
.purchaseStockId(4)
.purchaseTransactions(transactions)
.purchaseTotalCost(22.00)
.build();
dto = PurchaseDTO.builder()
.purchaseId(1)
.purchaseUserId(3)
.purchaseCompanyId(2)
.purchaseStockId(4)
.paymentStatus(0)
.purchaseTotalCost(22.00)
.purchaseTransactions(transactionDTOS)
.build();
}
#DisplayName("JUnit test for toDto method for <Purchase, PurchaseDTO> typemap using paymentStatus converter")
#Test
void toDtoUsingConverterForPurchaseTypeMap() {
PurchaseDTO testedDto = service.toDto(purchase);
assertThat(testedDto).isEqualTo(dto);
}
}
stack trace of error
org.modelmapper.MappingException: ModelMapper mapping errors:
1) Converter com.hrc.hrcweb.ModelMapperConfig$1$$Lambda$1240/0x00000008013e8ea0#5f5efbfc failed to convert com.hrc.hrcweb.entities.Purchase to java.lang.Integer.
1 error
at org.modelmapper.internal.Errors.throwMappingExceptionIfErrorsExist(Errors.java:380)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:80)
at org.modelmapper.ModelMapper.mapInternal(ModelMapper.java:573)
at org.modelmapper.ModelMapper.map(ModelMapper.java:406)
at com.hrc.hrcweb.servises.PurchaseService.toDto(PurchaseService.java:139)
at com.hrc.hrcweb.servises.PurchaseService$$FastClassBySpringCGLIB$$ffc82405.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy.invokeMethod(CglibAopProxy.java:386)
at org.springframework.aop.framework.CglibAopProxy.access$000(CglibAopProxy.java:85)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:704)
at com.hrc.hrcweb.servises.PurchaseService$$EnhancerBySpringCGLIB$$485f630d.toDto(<generated>)
at com.hrc.hrcweb.servises.PurchaseServiceTest.toDtoUsingConverterForPurchaseTypeMap(PurchaseServiceTest.java:93)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Caused by: java.lang.NullPointerException: Cannot invoke "com.hrc.hrcweb.entities.Purchase.getPurchaseTransactions()" because "this.source" is null
at com.hrc.hrcweb.ModelMapperConfig$1.lambda$configure$0(ModelMapperConfig.java:68)
at org.modelmapper.internal.MappingEngineImpl.convert(MappingEngineImpl.java:306)
at org.modelmapper.internal.MappingEngineImpl.setDestinationValue(MappingEngineImpl.java:243)
at org.modelmapper.internal.MappingEngineImpl.propertyMap(MappingEngineImpl.java:187)
at org.modelmapper.internal.MappingEngineImpl.typeMap(MappingEngineImpl.java:151)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:105)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:71)
... 77 more
What am i doing wrong?
After meny hours, i couldn't find any solution to map additional properties or map some expressions to perform some custom calculations for DTO objects properties using model mapper, i had to switch to Mapstuct for these kind of operations, it has some nice custom mapping of target property to expression=java(anymethod) and u can use any method to map target, it's very convenient. example perhaps someone will find this information usefull.
I solved everything with this piece of code
#Mapping(target = "paymentStatus", expression = "java(getPaymentStatus(purchase))")
PurchaseDTO toDto(Purchase purchase);
and this custom method calculating status
default Integer getPaymentStatus(Purchase purchase){
Integer status;
if(purchase.getPurchaseTransactions()==null){
status = 0;
}
double result = 0;
double sum = 0;
double total = purchase.getPurchaseTotalCost();
for(Transaction transaction: purchase.getPurchaseTransactions()) {
sum += transaction.getTransactionAmount();
result = sum/total;
}
if(result==0){
status=0;
}else if (result==1){
status=2;
}else{
status=1;
}
return status;
}

findById causes StackOverflowError but findAll workds fine

I'm having a strange problem with a spring boot endpoint that calls JpaRepository findById(). When ever I send a GET request to the endpoint /v1/goals/{id} a stack overflow error occurs, while GET requests to /v1/goals work fine.
Edit: added the error message to the bottom
Simplified Controller class:
#RestController
public class GoalController {
private final GoalServiceImpl service;
#Autowired
GoalController(GoalServiceImpl service) { this.service = service; }
#GetMapping("/v1/goals")
ResponseEntity<List<Goal>> allGoals() { return new ResponseEntity<>(service.getGoals(), HttpStatus.OK); }
#GetMapping("/v1/goals/{id}")
ResponseEntity<String> singleGoal(#PathVariable Long id) {
return new ResponseEntity<>(service.getGoalById(id).toString(), HttpStatus.OK);
}
}
Simplified Service class:
#Service
public class GoalServiceImpl implements GoalService {
private final GoalRepository repository;
#Autowired
public GoalServiceImpl(GoalRepository repository) { this.repository = repository; }
public Goal getGoalById(Long id) {
return repository
.findById(id)
.orElseThrow(() -> new GoalNotFoundException(id));
}
public List<Goal> getGoals() { return repository.findAll(); }
}
Simplified Entity class:
#NoArgsConstructor
#Data
#Entity
public class Goal {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long goalId;
#ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "user_id")
#JsonIgnore
private User user;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "goal")
#JsonIgnoreProperties(value = "goal")
private List<Milestone> milestones;
}
Simplified Milestone Entity:
#NoArgsConstructor
#Data
#Entity
public class Milestone {
#Id #GeneratedValue(strategy = GenerationType.IDENTITY)
private Long milestone_id;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "user_id")
#JsonIgnore
private User user;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "goal_id")
private Goal goal;
Simplified User Entity:
#NoArgsConstructor
#Data
#Entity
public class User {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long userId;
private String name;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
#JsonIgnoreProperties(value = "user")
private List<Goal> goals;
}
Error message:
java.lang.StackOverflowError: null
at org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor.intercept(ByteBuddyInterceptor.java:56) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.proxy.ProxyConfiguration$InterceptorDispatcher.intercept(ProxyConfiguration.java:95) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at com.motivate.api.user.User$HibernateProxy$KaIclPZ9.toString(Unknown Source) ~[classes/:na]
at java.base/java.lang.String.valueOf(String.java:2951) ~[na:na]
at com.motivate.api.goal.Goal.toString(Goal.java:16) ~[classes/:na]
at java.base/java.lang.String.valueOf(String.java:2951) ~[na:na]
at java.base/java.lang.StringBuilder.append(StringBuilder.java:168) ~[na:na]
at java.base/java.util.AbstractCollection.toString(AbstractCollection.java:473) ~[na:na]
at org.hibernate.collection.internal.PersistentBag.toString(PersistentBag.java:622) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at java.base/java.lang.String.valueOf(String.java:2951) ~[na:na]
at com.motivate.api.user.User.toString(User.java:11) ~[classes/:na]
at jdk.internal.reflect.GeneratedMethodAccessor58.invoke(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor.intercept(ByteBuddyInterceptor.java:56) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.proxy.ProxyConfiguration$InterceptorDispatcher.intercept(ProxyConfiguration.java:95) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at com.motivate.api.user.User$HibernateProxy$KaIclPZ9.toString(Unknown Source) ~[classes/:na]
Solution
provided by Chris and PaulD in the comments:
#GetMapping("/v1/goals/{id}")
ResponseEntity<Goal> singleGoal(#PathVariable Long id) {
return new ResponseEntity<>(service.getGoalById(id), HttpStatus.OK);
}
Remove the toString() as that causes the whole object to be serialised by lombok which doesn't take into account the jackson annotations. Change ResponseEntity to be of type Goal and pass in the whole entity.

java.lang.OutOfMemoryError: Java heap space Hibernate entityIsPersistent

I am reading 5gb of XML file using the below code and processing that data into Database using spring dataJpa, this below is just sample logic we are closing the inpustream and aswell xsr object.
XMLInputFactory xf=XMLInputFactory.newInstance();
XMLStreamReader xsr=xf.createXMLStreamReader(new InputStreamReader(new FileInputStream("test.xml"))
i have configured the max 8GB(ie -xms7000m and -xmx8000m) of heap memory But its getting the below hibernate heap issue when saving the data. it inserted around 700000 data total of 2100000
[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.OutOfMemoryError: Java heap space] with root cause
java.lang.OutOfMemoryError: Java heap space
at java.base/java.util.IdentityHashMap.resize(IdentityHashMap.java:472) ~[na:na]
at java.base/java.util.IdentityHashMap.put(IdentityHashMap.java:441) ~[na:na]
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsPersistent(DefaultPersistEventListener.java:159) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:124) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.internal.SessionImpl$$Lambda$1620/0x00000008010a3040.applyEventToListener(Unknown Source) ~[na:na]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:113) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.internal.SessionImpl.persistOnFlush(SessionImpl.java:765) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.engine.spi.CascadingActions$8.cascade(CascadingActions.java:341) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:492) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:416) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:218) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:525) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:456) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:419) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:218) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:151) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:158) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:148) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:81) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.internal.SessionImpl$$Lambda$1597/0x0000000801076040.accept(Unknown Source) ~[na:na]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1362) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:453) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3212) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2380) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:447) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:40) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101) ~[hibernate-core-5.4.22.Final.jar:5.4.22.Final]
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:534) ~[spring-orm-5.2.10.RELEASE.jar:5.2.10.RELEASE]
As per the above trace logs it seems some issue with hibernate save casacade , but not able to figured out , below are the entity classes which uses to save the data in databse.
#Data
#EqualsAndHashCode
#Builder(toBuilder = true)
#NoArgsConstructor(access = AccessLevel.PRIVATE)
#AllArgsConstructor(access = AccessLevel.PRIVATE)
public class UMEnityPK implements Serializable {
private static final long serialVersionUID=1L;
private String batchId;
private Long batchVersion;
private BigInteger umId;
}
#Data
#Builder(toBuilder = true)
#NoArgsConstructor(access = AccessLevel.PRIVATE)
#AllArgsConstructor(access = AccessLevel.PRIVATE)
#EqualsAndHashCode(of = {"batchId", "batchVersion", "umId"})
#Entity
#Table(name ="um_base")
#IdClass(UMEnityPK.class)
public class UMBase {
#Id private String batchId;
#Id private Long batchVersion;
#Id private BigInteger umId;
private String firstName;
private String lastName;
private String umType;
private String umLevel;
#OneToMany(mappedBy = "umBase", cascade = CascadeType.ALL)
private List<UMAddress> umAddresses;
#OneToMany(mappedBy = "umBase", cascade = CascadeType.ALL)
private List<UMIdentifier> umIdentifiers;
#OneToOne(mappedBy = "umBase", cascade = CascadeType.ALL)
private UMHierarchy umHierarchy;
}
#Data
#Builder(toBuilder = true)
#NoArgsConstructor(access = AccessLevel.PRIVATE)
#AllArgsConstructor(access = AccessLevel.PRIVATE)
#EqualsAndHashCode(of = {"id"})
#Entity
#Table(name = "um_identifier")
public class UMIdentifier {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "um_address")
#SequenceGenerator(name = "um_address", sequenceName = "SEQ_UM_ADDRESS", allocationSize = 1)
private Long id;
private String idValue;
private String idType;
private String groupType;
#ManyToOne
#JoinColumns({
#JoinColumn(name = "BATCH_ID", referencedColumnName = "batchId"),
#JoinColumn(name = "BATCH_VERSION", referencedColumnName = "batchVersion"),
#JoinColumn(name = "UM_ID", referencedColumnName = "umId")
})
private UMBase umBase;
}
#Data
#Builder(toBuilder = true)
#NoArgsConstructor(access = AccessLevel.PRIVATE)
#AllArgsConstructor(access = AccessLevel.PRIVATE)
#EqualsAndHashCode(of = {"batchId", "batchVersion", "umId"})
#Entity
#Table(name ="um_hierarchy")
public class UMHierarchy {
#Id
private String batchId;
#Id private Long batchVersion;
#Id private BigInteger umId;
private String hierarchyTpe;
private String umStatusCode;
private String immediateParentId;
private Date hierarchyDate;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumns({
#JoinColumn(name = "BATCH_ID", referencedColumnName = "batchId"),
#JoinColumn(name = "BATCH_VERSION", referencedColumnName = "batchVersion"),
#JoinColumn(name = "UM_ID", referencedColumnName = "umId")
})
private UMBase umBase;
}
#Data
#Builder(toBuilder = true)
#NoArgsConstructor(access = AccessLevel.PRIVATE)
#AllArgsConstructor(access = AccessLevel.PRIVATE)
#EqualsAndHashCode(of = {"id"})
#Entity
#Table(name = "um_address")
public class UMAddress {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "um_address")
#SequenceGenerator(name = "um_address", sequenceName = "SEQ_UM_ADDRESS", allocationSize = 1)
private Long id;
private String addressType;
private String addressLine1;
private String getAddressLine2;
private String city;
private String state;
private String postalCode;
private String country;
#ManyToOne
#JoinColumns({
#JoinColumn(name = "BATCH_ID", referencedColumnName = "batchId"),
#JoinColumn(name = "BATCH_VERSION", referencedColumnName = "batchVersion"),
#JoinColumn(name = "UM_ID", referencedColumnName = "umId")
})
private UMBase umBase;
}
Is there any issues with hibernate entity mapping which eating of the memory
After checking the heap dump, the issue is with the org.hibernate.engine.StatefulPersistenceContext -> org.hibernate.util.IdentityMap memory leak , so used the below way and worked fine , create a custom JPARepository and have below sample method logic.
public <S extends T> void saveInBatch(Iterable<S> entities) {
if (entities == null) {
return;
}
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction entityTransaction = entityManager.getTransaction();
try {
entityTransaction.begin();
int i = 0;
for (S entity : entities) {
if (i % batchSize == 0 && i > 0) {
entityTransaction.commit();
entityTransaction.begin();
entityManager.clear();
}
entityManager.persist(entity);
i++;
}
entityTransaction.commit();
} catch (RuntimeException e) {
if (entityTransaction.isActive()) {
entityTransaction.rollback();
}
throw e;
} finally {
entityManager.close();
}
}
}
When dealing with converting datasets that big you need to do that in batches. Read 100 records from the xml, convert them to entities, save each of them with em.persist(record), then call em.flush() and em.clear() to remove them from Hibernate, then clear them from your local collection, then manually invoke the garbage collector using System.gc(). You may even want to use Hibernate's batch processing as described in this tutorial.
In pseudocode this would be:
boolean finished = false;
List<Entity> locals = new ArrayList<>(100);
while (!finished) {
for (int records = 0; records < 100; records++) {
Entity ent = readEntityFrom(xml);
// readEntity function must return null when no more remain to read
if (ent == null) {
finished = true;
break;
}
locals.add(ent);
}
for (Entity ent : locals) em.persist(ent);
em.flush(); // send any that are still waiting to the database
em.clear(); // remove references Hibernate holds to these entities
locals.clear(); // remove references we hold to these entities
// now all these entity references are weak and can be garbage-collected
System.gc(); // purge them from memory
}
Also you may want to manually begin and commit a transaction around each insert loop to ensure the database isn't holding everything for your entire import, or it might run out of memory instead of your java application.

EntityNotFoundException on save function

I am trying to save Entity with one to many relation. It throws EntityNotFoundException when trying to save the entity
I did some research but not able to find any solution to this
Order Entity:
#Data
#Component
#Entity
#Slf4j
#Table (name = ORDER_TABLE_NAME)
public class OrderEntity {
//== Order Details
#Id
#GeneratedValue(generator = "uuid")
#GenericGenerator(name = "uuid", strategy = "uuid2")
#Column(name = ORDER_ID_COLUMN)
private String orderIdGuid;
#Column (name = ORDER_BOOKED_DATETIME_COLUMN)
private LocalDateTime orderBookedDate;
#Column(name = ORDER_STATUS_COLUMN)
private String orderStatus;
#OneToMany( cascade={CascadeType.ALL}, orphanRemoval = true)
#JoinColumn(name= ORDER_ID_COLUMN)
#Autowired
private List<ProductEntity> products;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name = ORDER_ID_COLUMN)
private List<Followup> followups;
Product Entity:
#Data
#Component
#Entity
#Table (name=ORDER_PRODUCT_TABLE)
public class ProductEntity {
#Id
#GeneratedValue(generator = "uuid")
#GenericGenerator(name = "uuid", strategy = "uuid2")
#Column (name = PRODUCT_PRIMARY_ID)
private String product_primary_id;
//=== defined by constants
#Column(name = PRODUCT_NAME)
private String productName;
DAOClass:
#Component
#Data
#Slf4j
public class DAOOrderRepository {
#Autowired
OrderRepository orderRepository;
public void saveOrderEntity(OrderEntity orderEntity) {
orderEntity.setOrderUpdatedDate(LocalDate.now());
orderRepository.save(orderEntity);
}
public OrderEntity findOrderByOrderId(String orderId) {
return orderRepository.findOrderEntityByOrderIdGuid(orderId);
}
public List<OrderEntity> findAllOrdersByEmployeeId(String employeeId) {
return orderRepository.findBySalesRepEmployeeId(employeeId);
}
}
Repository:
#Repository
public interface OrderRepository extends JpaRepository<OrderEntity,String> {
List<OrderEntity> findBySalesRepEmployeeId(String employeeId);
OrderEntity findOrderEntityByOrderIdGuid(String orderIdGuid);
}
Exception:
org.springframework.orm.jpa.JpaObjectRetrievalFailureException: Unable to
find
com.app.apicore.Entities.OrderServiceEntity.ProductEntity.ProductEntity
with id 03350d2a-15cf-46da-ba2c-58aeec79db9a; nested exception is
javax.persistence.EntityNotFoundException: Unable to find
com.app.apicore.Entities.OrderServiceEntity.ProductEntity.ProductEntity
with id 03350d2a-15cf-46da-ba2c-58aeec79db9a
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:378)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:255)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:527)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:138)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy111.save(Unknown Source)
at com.app.apicore.Apis.DAOOrderRepository.saveOrderEntity(DAOOrderRepository.java:24)
Each order is a new order record. So when i try to save the order record for the first time, it saves the order data correct. It saves the order data correct for second time to. But on the third time throws exception.

Spring Boot: Cannot construct instance of … : no int/Int-argument constructor/factory method to deserialize from Number value (1);

I'm trying to read a response from a rest service with RestTemplate (Spring Boot) But when I run the tomcat server in the eclipse I always get this error: no int/Int-argument constructor/factory method to deserialize from Number value (1);
The spring boot REST API pom.xml is as follows:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-framework.version>5.1.8.RELEASE</spring-framework.version>
<jackson.version>2.9.9</jackson.version>
<oauth2.version>2.3.4.RELEASE</oauth2.version>
</properties>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate5</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>${oauth2.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.9</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.9</version>
</dependency>
I have tried building the rest api with:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
But it throw the same error.
I have these two classes in my Spring boot REST API:
Route.java
#Entity
#Table(name = "ROUTE")
#JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id", scope = Route.class)
public class Route implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator="native")
#GenericGenerator(name = "native", strategy = "native")
#Column(name = "ID", updatable = false, nullable = false)
private Long id = null;
#Column(name = "ORIGIN", nullable = false)
#NotEmpty(message = "*This field is required!")
private String origin;
#Column(name = "DESTINATION", nullable = false)
#NotEmpty(message = "*This field is required!")
private String destination;
#Column(name = "STATUS", nullable = true)
private String status;
#Column(name = "DATE_CREATED", nullable = true)
#JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd")
#Temporal(TemporalType.DATE)
private Date dateCreated;
#Column(name = "TOKEN", nullable = false)
private String token;
#Column(name = "SYNC_STATUS", nullable = false)
private String syncStatus;
/*#OneToMany(cascade = CascadeType.ALL, mappedBy = "route", fetch = FetchType.LAZY)
#JsonBackReference(value = "trips")
private Set<Trip> trips = new HashSet<>();*/
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name="ROUTE_BRANCH_ID", referencedColumnName = "ID", nullable = false)
//#JsonManagedReference
private Branch branch;
...
}
Trip.java
#Entity
#Table(name = "TRIP")
#JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id", scope = Trip.class, resolver = CustomObjectIdResolver.class)
public class Trip implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator="native")
#GenericGenerator(name = "native", strategy = "native")
#Column(name = "ID", updatable = false, nullable = false)
private Long id = null;
#Column(name = "TRIP_NUMBER", nullable = false)
#NotEmpty(message = "*This field is required!")
private String tripNumber;
#Column(name = "DEPARTURE_DATE", nullable = false)
#Temporal(TemporalType.DATE)
#JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd")
//#DateTimeFormat(pattern = "dd/MM/yyyy")
private Date departureDate;
#Column(name = "DEPARTURE_TIME", nullable = false)
#NotEmpty(message = "*This field is required!")
private String departureTime;
#Transient
private int availableSeatsNo;
#Column(name = "TRIP_FARE")
private double tripFare;
#Column(name = "TYPE", nullable = false)
#NotEmpty(message = "*This field is required!")
private String type;
#Column(name = "STATUS", nullable = false)
private String status;
#Column(name = "DISPATCHED")
private boolean dispatched;
#Column(name = "LOADING_SEQUENCE", nullable = false)
private String loadingSequence;
#Column(name = "BRANCH_NAME", nullable = false)
private String branchName;
#Column(name = "TRANSPORT_INCOME")
private double transportIncome;
#Column(name = "TOTAL_INCOMES")
private double totalIncomes;
#Column(name = "TOTAL_EXPENSES")
private double totalExpenses;
#Column(name = "BALANCE")
private double balance;
#Column(name = "CHECKED_BY", nullable = true)
private String checkedBy;
#Column(name = "TOKEN", nullable = false)
private String token;
#Column(name = "SYNC_STATUS", nullable = false)
private String syncStatus;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "trip", fetch = FetchType.LAZY)
#JsonBackReference(value = "ticketBookings")
private Set<TicketBooking> ticketBookings = new HashSet<>();
#OneToMany(cascade = CascadeType.ALL, mappedBy = "trip", fetch = FetchType.LAZY)
#JsonBackReference(value = "tripExpenses")
private Set<TripExpense> tripExpenses = new HashSet<>();
#OneToMany(cascade = CascadeType.ALL, mappedBy = "trip", fetch = FetchType.LAZY)
#JsonBackReference(value = "luggageIncomes")
private Set<LuggageIncome> luggageIncomes = new HashSet<>();
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name="TRI_VEHICLE_ID", referencedColumnName = "ID", nullable = false)
//#JsonManagedReference
private Vehicle vehicle;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name="TRI_ROUTE_ID", referencedColumnName = "ID", nullable = false)
//#JsonManagedReference
private Route route;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name="TRI_DRIVER_ID", referencedColumnName = "ID", nullable = false)
//#JsonManagedReference
private Driver driver;
/*#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name="TRI_BRANCH_ID", referencedColumnName = "ID", nullable = false)
//#JsonManagedReference
private Branch branch;*/
/*#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name="TRI_CURRENCY_ID", referencedColumnName = "ID", nullable = true)
//#JsonManagedReference
private Currency currency;*/
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name="TRI_LEDGER_ACCOUNT_ID", referencedColumnName = "ID", nullable = false)
//#JsonManagedReference
private LedgerAccount ledgerAccount;
....
}
TripController.java
#RestController
#RequestMapping("/api/trip")
public class TripController {
#Autowired
private TripService resourceService;
...
#RequestMapping(value="/dispatched-and-branch/{dispatched}/{branchName}", method = RequestMethod.GET)
public ResponseEntity<?> getByDispatchedAndBranchName(#PathVariable("dispatched") boolean dispatched, #PathVariable("branchName") String branchName) {
List<Trip> resourceList = resourceService.getByDispatchedAndBranchName(dispatched, branchName);
return new ResponseEntity<>(resourceList, HttpStatus.OK);
}
...
}
And I'm trying to read a response from the rest service with RestTemplate (Spring Boot) as follows:
#Component
public class ScheduledTasks {
....
boolean dispatched = false;
String branchName = "branchName";
String dispatchedAndBranchUrl = "http://localhost:8089/primeerp-api/api/trip/dispatched-and-branch";
Trip[] tripsArr = oauth2RestTemplate.getForObject(dispatchedAndBranchUrl + "/{dispatched}" + "/{branchName}", Trip[].class, dispatched, branchName);
...
}
I expect to get a list/array of Trip objects that have not been dispatched in a particular branch, rather it returns the following RestClientException:
org.springframework.web.client.RestClientException: Error while extracting response for type [class [Lcom.fg.primeerp.model.Trip;] and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `com.fg.primeerp.model.Route` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (1); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.fg.primeerp.model.Route` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (1)
at [Source: (PushbackInputStream); line: 1, column: 4393] (through reference chain: java.lang.Object[][1]->com.fg.primeerp.model.Trip["route"])
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:117) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:737) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.security.oauth2.client.OAuth2RestTemplate.doExecute(OAuth2RestTemplate.java:128) ~[spring-security-oauth2-2.3.4.RELEASE.jar:na]
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:670) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:311) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at com.fg.primeerp.scheduler.ScheduledTasks.createOrUpdateTrip2(ScheduledTasks.java:1735) ~[classes/:0.0.1-SNAPSHOT]
at com.fg.primeerp.scheduler.ScheduledTasks$$FastClassBySpringCGLIB$$b2f2eb1e.invoke(<generated>) ~[classes/:0.0.1-SNAPSHOT]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749) ~[spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295) ~[spring-tx-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) ~[spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at com.fg.primeerp.scheduler.ScheduledTasks$$EnhancerBySpringCGLIB$$652aa0ce.createOrUpdateTrip2(<generated>) ~[classes/:0.0.1-SNAPSHOT]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_144]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_144]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_144]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_144]
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [na:1.8.0_144]
at java.util.concurrent.FutureTask.runAndReset(Unknown Source) [na:1.8.0_144]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(Unknown Source) [na:1.8.0_144]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) [na:1.8.0_144]
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_144]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.8.0_144]
at java.lang.Thread.run(Unknown Source) [na:1.8.0_144]
Caused by: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `com.fg.primeerp.model.Route` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (1); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.fg.primeerp.model.Route` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (1)
at [Source: (PushbackInputStream); line: 1, column: 4393] (through reference chain: java.lang.Object[][1]->com.fg.primeerp.model.Trip["route"])
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:245) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:227) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:102) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
... 27 common frames omitted
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.fg.primeerp.model.Route` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (1)
at [Source: (PushbackInputStream); line: 1, column: 4393] (through reference chain: java.lang.Object[][1]->com.fg.primeerp.model.Trip["route"])
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1343) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1032) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.deser.ValueInstantiator.createFromInt(ValueInstantiator.java:262) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromInt(StdValueInstantiator.java:356) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromNumber(BeanDeserializerBase.java:1324) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:173) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:161) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:369) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:195) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:21) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013) ~[jackson-databind-2.9.9.jar:2.9.9]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3084) ~[jackson-databind-2.9.9.jar:2.9.9]
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:239) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
... 29 common frames omitted
All my efforts to solve this problem proved abortive. Please, help me out.

Resources