java.lang.OutOfMemoryError: Java heap space Hibernate entityIsPersistent - spring-boot

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.

Related

Spring JPA 2 nested many to many relationship

I am having a problem with my many to many relationship. Basically, here is what I am trying to do.
I have 2 many to many tables that are nested, as seen on the following image.
Db diagram
When compiling my code, I get the following error:
Caused by: java.sql.SQLSyntaxErrorException: Unknown column 'weeks0_.employee_project_employee_id' in 'field list'
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120) ~[mysql-connector-java-8.0.18.jar:8.0.18]
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) ~[mysql-connector-java-8.0.18.jar:8.0.18]
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-java-8.0.18.jar:8.0.18]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953) ~[mysql-connector-java-8.0.18.jar:8.0.18]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeQuery(ClientPreparedStatement.java:1003) ~[mysql-connector-java-8.0.18.jar:8.0.18]
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52) ~[HikariCP-3.4.1.jar:na]
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java) ~[HikariCP-3.4.1.jar:na]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:57) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
So I understand that I have a problem with the weeks.
here are my entities:
Week:
package com.achsogo.rpt.entity;
import javax.persistence.*;
import java.util.Set;
#Entity
#Table(name="week")
public class Week {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private int weekNumber;
private int year;
#OneToMany(mappedBy = "week", cascade = CascadeType.ALL, orphanRemoval = true, fetch =
FetchType.EAGER)
private Set<EmployeeProjectWeek> employeeProjects;
public Week() {
}
public Week(int weekNumber, int year) {
this.weekNumber = weekNumber;
this.year = year;
} //Getter and Setters
Project:
import javax.persistence.*;
import java.util.*;
#Entity
#Table(name = "project")
public class Project {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String alias;
private String pspElement;
private int contractValue;
private int plannedCost;
private int plannedHours;
private int assignedHours;
private Date startDate;
private Date endDate;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "project", orphanRemoval = true, fetch =
FetchType.EAGER)
private Set<ProjectAP> projectAPS;
#ManyToOne
private Department department;
#OneToMany(mappedBy = "project", cascade = CascadeType.ALL, orphanRemoval = true, fetch =
FetchType.EAGER)
private Set<EmployeeProject> employees;
//Empty constructor
public Project(){}
//constructor for new project with default names
public Project(String alias){
this.alias = alias;
}
Employee:
#Entity
#Table(name = "employee")
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
private String email;
private int employeeNumber;
private String acronym;
private int availability;
#OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, orphanRemoval = true, fetch =
FetchType.EAGER)
private Set<EmployeeProject> projects;
#ManyToOne
private Department department;
#ManyToOne
private Role role;
Table between Project and Employee (with the class to create the ID):
EmployeeProjectID:
#Embeddable
public class EmployeeProjectId implements Serializable {
private Long projectId;
private Long employeeId;
private EmployeeProjectId(){}
public EmployeeProjectId(Long projectId, Long employeeId){
this.employeeId = employeeId;
this.projectId = projectId;
}
EmployeeProject: It is here that the weeks are being called (If I am not mistaken)
#Entity
#Table(name = "project_employee")
public class EmployeeProject {
#EmbeddedId
private EmployeeProjectId id;
#ManyToOne(fetch = FetchType.EAGER)
#MapsId("projectId")
private Project project;
#ManyToOne(fetch = FetchType.EAGER)
#MapsId("employeeId")
private Employee employee;
#Column(name = "amount_time")
private int amountTime = 0;
#Column(name = "is_project_leader")
private boolean isProjectLeader = false;
#OneToMany(mappedBy = "employeeProject", cascade = CascadeType.ALL, orphanRemoval = true, fetch =
FetchType.EAGER)
private Set<EmployeeProjectWeek> weeks;
public EmployeeProject(){}
And now the table between Week and Employee Project:
EmployeeProjectWeekId: To create the ID for the nested many to many table:
#Embeddable
public class EmployeeProjectWeekId implements Serializable {
private EmployeeProjectId employeeProjectId;
private Long weekId;
private EmployeeProjectWeekId(){}
And finally the EmployeeProjectweek:
#Entity
#Table(name="project_employee_week")
public class EmployeeProjectWeek {
#EmbeddedId
private EmployeeProjectWeekId id;
#ManyToOne(fetch = FetchType.EAGER)
#MapsId("weekId")
private Week week;
#ManyToOne(fetch = FetchType.EAGER)
#MapsId("employeeProjectId")
private EmployeeProject employeeProject;
#Column(name="amount_time")
private int amountTime = 0;
#Column(name="is_project_leader")
private boolean isProjectLeader= false;
public EmployeeProjectWeek(Week week, EmployeeProject employeeProject) {
this.week = week;
this.employeeProject = employeeProject;
this.id = new EmployeeProjectWeekId(employeeProject.getId(), week.getId());
}
Does anyone has a clue where I have done an error? Thanks in advance for your time!
It was a naming problem. I solved this by dropping all the tables in my DB and having Spring to automatically generate the tables. Now everything works well.
I entered the following lines in my application.properties:
spring.jpa.hibernate.ddl=true
spring.jpa.hibernate.ddl-auto=update

How to map an entity as java.util.Map with spring Data JPA?

I have such entities:
Bonus_Request entity:
#Entity
#Table(name = "bonus_request")
public class BonusRequest {
//some code above...
#OneToMany(fetch = FetchType.EAGER, mappedBy = "bonusRequest")
#JsonManagedReference(value = "parameter-bonus_request")
private Set<BonusRequestParameter> parameters;
}
Bonus_Request_Parameter entity:
#Entity
#Table(name = "bonus_request_parameter")
public class BonusRequestParameter {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Size(max = 30)
#Column(name = "parameter", nullable = false)
private String parameter;
#Size(max = 50)
#Column(name = "value", nullable = false)
private String value;
#JoinColumn(name = "bonus_request_id", nullable = false)
#ManyToOne(fetch = FetchType.LAZY)
#JsonBackReference(value = "parameter-bonus_request")
private BonusRequest bonusRequest;
}
I wonder if it is possible to map the BonusRequestParameter entity as a java.util.Map field in the BonusRequest entity.
For example:
#Entity
#Table(name = "bonus_request")
public class BonusRequest {
#OneToMany(fetch = FetchType.EAGER, mappedBy = "bonusRequest")
private Map<String, String> parameters; //String parameter, String value
}
I use:
Spring Data JPA - 2.1.7
PostgreSQL DB - 10.7
This will work. It loads the map eagerly by default.
#Entity
#Table(name = "bonus_request")
public class BonusRequest {
...
#ElementCollection
private Map<String, String> parameters; //String parameter, String value
}
Resolved with this:
#ElementCollection(fetch = FetchType.EAGER)
#CollectionTable(name = "bonus_request_parameter",
joinColumns = {#JoinColumn(name = "bonus_request_id", referencedColumnName = "id")})
#MapKeyColumn(name = "parameter")
#Column(name = "value")
private Map<String, String> parameters;
Thank you for help.

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.

UUID Mapping in hibernate

I have mapped a table to my table and trying to add some values in it. but I am getting errors as below
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'create, delete, read, role_id, update, id) values
(_binary'ØN_WlAs—\niÊnÙ' at line 1
my entities are
RoleSettings.java
#Entity #Table(name = "role_settings")
#Getter #Setter #Data
public class RoleSettings implements Serializable {
private static final long serialVersionUID = 8862104773442047690L;
#Id
#GeneratedValue(generator = "uuid2")
#GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
private UUID id;
#ManyToOne
#JoinColumn(name = "role_id", referencedColumnName = "id", foreignKey = #ForeignKey(name = "role_settings_iam_role_FK"))
private RoleMaster roleId;
}
RoleMaster.java
#Entity #Table(name = "role")
#Getter #Setter #Data
public class RoleMaster implements Serializable {
private static final long serialVersionUID = 1792968151371176640L;
#Id
#GeneratedValue(generator = "uuid2")
#GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
private UUID id;
#Column(name = "name", nullable = false, length = 255)
private String name;
}
RoleSettingsRepository.java
public interface RoleSettingsRepository extends JpaRepository<RoleSettings, UUID>{}
RoleSettingsService.java
#Service
Class RoleSettingsService {
#Autowired
private RoleSettingsRepository roleSettingsRepository;
public BaseDTO create(RoleSettings roleSettings) {
BaseDTO response = new BaseDTO();
RoleSettings newRoleSettings = new RoleSettings();
try {
newRoleSettings.setRoleId(roleSettings.getRoleId());
newRoleSettings.setAppAccessId(roleSettings.getAppAccessId());
newRoleSettings.setCreate(roleSettings.getCreate());
newRoleSettings.setUpdate(roleSettings.getUpdate());
newRoleSettings.setRead(roleSettings.getRead());
newRoleSettings.setDelete(roleSettings.getDelete());
roleSettingsRepository.save(newRoleSettings);
response.setStatusCode(200);
} catch (Exception e) {
}
return response;
}
}
RoleSettingsController.java
#RestController
#RequestMapping("/v1/rolesettings")
public class RoleSettingsController {
#Autowired
private RoleSettingsService roleSettingsService;
#PostMapping("/post")
public BaseDTO create(#RequestBody RoleSettings roleSettings) {
BaseDTO response = roleSettingsService.create(roleSettings);
return response;
}
}
my json object
{ "roleId" :{"id": "b2e64c82-ab75-41d3-bb10-e9150f314807"} }
and my roleId is stored in database as type binary(16).
Check in your database data type of the id column. It has to be BINARY(16). And annotate your entity field as:
#Id
#GeneratedValue(generator = "uuid2")
#GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator")
#Column(columnDefinition = "BINARY(16)")
private UUID id;
Note that you nned to add a column definition in this case.

OneToOne in Hibernate causes StackOverflow Exception when calling Mongo save

I have two entities :
Invoice :
#Entity
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#Table(name = "invoices")
#JsonIgnoreProperties(ignoreUnknown = true)
public class Invoice implements Serializable {
private static final long serialVersionUID = 1L;
#GeneratedValue(generator = "uuid")
#GenericGenerator(name = "uuid", strategy = "uuid2")
#Column(columnDefinition = "CHAR(36)")
#Id
private String id;
#OneToOne(cascade = CascadeType.ALL, mappedBy = "invoice")
private InvoiceSequence invoiceSequence;
... // skipped for brevity
InvoiceSequence
#Entity
public class InvoiceSequence {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long seqId;
#OneToOne
#JoinColumn(name = "invoice_id", nullable = false)
#JsonIgnore
private Invoice invoice;
... // skipped for brevity
When calling mongo save,as in :
#Override
public Invoice save(Invoice invoice) {
Invoice savedInv = invoiceRepository.save(invoice);
InvoiceSequence seq = new InvoiceSequence();
seq.setInvoice(savedInv);
InvoiceSequence savedSeq = invoiceSequenceRepository.save(seq);
savedInv.setInvoiceSequence(savedSeq);
return savedInv;
}
i get :
java.lang.StackOverflowError
at java.lang.Class.isInstance(Native Method)
at java.lang.Class.cast(Class.java:3368)
at java.lang.invoke.DirectMethodHandle$Accessor.checkCast(DirectMethodHandle.java:418)
at java.lang.invoke.DirectMethodHandle.checkCast(DirectMethodHandle.java:487)
at com.vulog.billing.domain.Invoice_Accessor_5oixbb.getProperty(Unknown Source)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:432)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:425)
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:330)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writeInternal(MappingMongoConverter.java:425)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.writePropertyInternal(MappingMongoConverter.java:527)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$3.doWithPersistentProperty(MappingMongoConverter.java:437)
What am i missing?
Thanks for any help

Resources