Error LazyInitializationException on hibernate criteria + restriction (Spring) - java

I'm getting this error when getting a query with hibernate
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:167)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
at com.javalabs.web.dao.Task_$$_javassist_1.toString(Task_$$_javassist_1.java)
at java.lang.String.valueOf(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
at com.javalabs.web.dao.TaskAction.toString(TaskAction.java:175)
at java.lang.String.valueOf(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
at java.util.AbstractCollection.toString(Unknown Source)
at java.lang.String.valueOf(Unknown Source)
at org.junit.Assert.format(Assert.java:752)
at org.junit.Assert.failNotEquals(Assert.java:743)
at org.junit.Assert.assertEquals(Assert.java:118)
at com.javalabs.web.test.tests.TaskActionDaoTests.testTaskActionCreate(TaskActionDaoTests.java:120)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
JUnit test that throw the error
#Test
public void testTaskActionCreate() {
taskPriorityDao.saveOrUpdate(priority);
taskCategoryDao.saveOrUpdate(category);
taskStateDao.saveOrUpdate(state);
userDao.saveOrUpdate(user);
Date rightnow = Calendar.getInstance().getTime();
Task t1 = new Task("My first task", "This is a task", rightnow,
rightnow, category, priority, state, user, user, "okey", 0);
TaskAction ta1 = new TaskAction(t1, rightnow, "Task action 1",
"Task action 1 description", user);
TaskAction ta2 = new TaskAction(t1, rightnow, "Task action 2",
"Task action 2 description", user);
TaskAction ta3 = new TaskAction(t1, rightnow, "Task action 3",
"Task action 3 description", user);
TaskAction ta4 = new TaskAction(t1, rightnow, "Task action 4",
"Task action 4 description", user);
t1.addAction(ta1);
t1.addAction(ta2);
t1.addAction(ta3);
t1.addAction(ta4);
taskDao.save(t1);
Task t2 = taskDao.get(t1.getIdTask());
assertEquals("Should be 4 taskActions with getAllTaskActions.", 4,
taskActionDao.getAllTaskActions(t2.getIdTask()));
}
TaskActionDao.java
...
#SuppressWarnings("unchecked")
public List<TaskAction> getAllTaskActions(long idTask) {
Criteria crit = session().createCriteria(TaskAction.class);
crit.add(Restrictions.eq("task.idTask", idTask)); //error task.idTask?
return crit.list();
}
...
TaskAction.java
#Entity
#Table(name = "t_taskaction")
public class TaskAction {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "idTaskAction")
private long idTaskAction;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "idTask", nullable = false)
private Task task;
private Date date;
private String actionname;
private String description;
private int duration;
#ManyToOne
#JoinColumn(name = "idUser", nullable = false)
private User user;
private Date timestamp;
...
Task.java
#Entity
#Table(name = "t_task")
public class Task {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "idTask")
private long idTask;
...

It makes sense that you a get LazyInitializationException. Since you are using toString implicitly on TaskAction, task is trying to be accessed which is lazily loaded.
If you try assertEquals("Should be 4 taskActions with getAllTaskActions.", 4, taskActionDao.getAllTaskActions(t2.getIdTask()).size());

Related

Why does hibernate want to insert a new entity with the same key if it already exists?

I am having the following problem. I have pushed my example into GitHub.
If I want to persist an instance of my class PlayerStatistics then Hibernate tries to create an already existing entity of Matchday (specified as #ManyToOne) which I do not want to but I do not seem to get around it.
I am persisting in the init method of DemoApplicationTests.
#Before
public void init() {
final Matchday matchday = matchdayRepository.save(new Matchday(1));
final Club club1 = clubRepository.save(new Club("Klub1"));
final Club club2 = clubRepository.save(new Club("Klub2"));
final Match match = matchRepository.save(new Match(matchday, club1, club2));
final Player player = playerRepository.save(new Player(1, "Jan", "Kowalski", club1));
playerStatisticsRepository.save(new PlayerStatistics(matchday, player, match));
}
If I have it like above, then I get the following exception.
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [SYS_PK_10114]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:278)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:244)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:521)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:504)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:292)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy102.save(Unknown Source)
at com.example.DemoApplicationTests.init(DemoApplicationTests.java:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:59)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:97)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:207)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:45)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2934)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3434)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:89)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:582)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:456)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1407)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:477)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3170)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2384)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:467)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:146)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:220)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:68)
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
... 44 more
Caused by: java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: unique constraint or index violation; SYS_PK_10114 table: MATCHDAY
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.fetchResult(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.executeUpdate(Unknown Source)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:204)
... 62 more
Caused by: org.hsqldb.HsqlException: integrity constraint violation: unique constraint or index violation; SYS_PK_10114 table: MATCHDAY
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.Constraint.getException(Unknown Source)
at org.hsqldb.index.IndexAVLMemory.insert(Unknown Source)
at org.hsqldb.persist.RowStoreAVL.indexRow(Unknown Source)
at org.hsqldb.TransactionManager2PL.addInsertAction(Unknown Source)
at org.hsqldb.Session.addInsertAction(Unknown Source)
at org.hsqldb.Table.insertSingleRow(Unknown Source)
at org.hsqldb.StatementDML.insertSingleRow(Unknown Source)
at org.hsqldb.StatementInsert.getResult(Unknown Source)
at org.hsqldb.StatementDMQL.execute(Unknown Source)
at org.hsqldb.Session.executeCompiledStatement(Unknown Source)
at org.hsqldb.Session.execute(Unknown Source)
... 65 more
If I debug the HQL I can clearly see that Hibernate wants to insert a new row into the table Matchday even if it already exists.
Hibernate:
insert
into
Matchday
(matchdayNumber)
values
(?)
If I comment the last line of the init() method then it works OK, so the problem has to be in this part: playerStatisticsRepository.save(new PlayerStatistics(matchday, player, match))
#Before
public void init() {
final Matchday matchday = matchdayRepository.save(new Matchday(1));
final Club club1 = clubRepository.save(new Club("Klub1"));
final Club club2 = clubRepository.save(new Club("Klub2"));
final Match match = matchRepository.save(new Match(matchday, club1, club2));
final Player player = playerRepository.save(new Player(1, "Jan", "Kowalski", club1));
//playerStatisticsRepository.save(new PlayerStatistics(matchday, player, match));
}
What am I doing wrong here?
PlayerStatistics class looks like that.
#Entity
#IdClass(PlayerStatisticsId.class)
public class PlayerStatistics implements Serializable {
//...
#Id
#ManyToOne(optional = false)
#PrimaryKeyJoinColumn
private Player player;
#Id
#ManyToOne(optional = false)
#PrimaryKeyJoinColumn
private Matchday matchday;
#ManyToOne(optional = false)
#JoinColumns({ #JoinColumn(name = "matchday_matchdaynumber", referencedColumnName = "matchday_matchdaynumber"),
#JoinColumn(name = "hometeam_name", referencedColumnName = "hometeam_name") })
private Match match;
#Column(nullable = false)
private boolean playedFromTheFirstWhistleblow;
#Min(0)
#Column(nullable = false)
private int enteredTheFieldAtInSeconds;
#Min(0)
#Column(nullable = false)
private int leftTheFieldAtInSeconds;
#ElementCollection(fetch = FetchType.EAGER)
#CollectionTable
#MapKeyEnumerated(EnumType.STRING)
private Map<ScoreType, Integer> statistics = new HashMap<>();
//...
}
EDIT
If I want to manage it directly from the Player entity on the other hand. Then I receive an exception that the entity is already associated with the session, while it does not seem to be.
#Before
public void init() {
final Matchday matchday = matchdayRepository.save(new Matchday(1));
final Club club1 = clubRepository.save(new Club("Klub1"));
final Club club2 = clubRepository.save(new Club("Klub2"));
final Match match = matchRepository.save(new Match(matchday, club1, club2));
final Player player = new Player(1, "Jan", "Kowalski", club1);
player.addPlayerStatistics(new PlayerStatistics(matchday, player, match));
playerRepository.save(player);
}
org.springframework.dao.DataIntegrityViolationException: A different object with the same identifier value was already associated with the session : [com.example.model.Player#1]; nested exception is javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [com.example.model.Player#1]
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:410)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:246)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:491)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy99.save(Unknown Source)
at com.example.DemoApplicationTests.init(DemoApplicationTests.java:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [com.example.model.Player#1]
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:116)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:155)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:162)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:899)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:855)
at org.hibernate.engine.spi.CascadingActions$6.cascade(CascadingActions.java:261)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:391)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:316)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:155)
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:424)
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:356)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:319)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:155)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:104)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:445)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:238)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:300)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:169)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:68)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:864)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:845)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:850)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298)
at com.sun.proxy.$Proxy97.merge(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:509)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:503)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:488)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:460)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
... 37 more
The problem here was in the PlayerStatisticsId and the way it was defined.
Originally it looked like this.
public class PlayerStatisticsId implements Serializable {
//..
private long player;
private int matchday;
public long getPlayer() {
return player;
}
public int getMatchday() {
return matchday;
}
#Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof PlayerStatisticsId) {
final PlayerStatisticsId o = (PlayerStatisticsId) obj;
return o.matchday == matchday && o.player == player;
} else {
return false;
}
}
}
I could have sworn that I read somewhere that only the primitives/basic types could be used in a class that is used for #ClassId. It does not seem to be the case though.
After changing it to
public class PlayerStatisticsId implements Serializable {
//...
private Player player;
private Matchday matchday;
public Player getPlayer() {
return player;
}
public Matchday getMatchday() {
return matchday;
}
#Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof PlayerStatisticsId) {
final PlayerStatisticsId o = (PlayerStatisticsId) obj;
return o.matchday.equals(matchday) && o.player.equals(player);
} else {
return false;
}
}
}
It does seem to work. I am receiving a completely different exception now but it is a case for a separate question.

java.lang.illegalargumentexception cannot set java.lang.string field to java.lang.String

I am deleloping a small spring and hibernate program, And i want to get sum of values from database. For that i written below code
public double getDataFromDb(String num) {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
double result=0;
Query getSumquery=(Query)session.createQuery("select sum(amount) from User_Master where =:num");
getSumquery.setParameter("num",num);
List list =getSumquery.list();
result=(double) list.get(0);
tx.commit();
Here i am getting exception in list line.When running from junit testcasethe Exception is like below
org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.abc.process.hbmfiles.Number.num
at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:35)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:183)
at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:3596)
at org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:3312)
at org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:181)
at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:218)
at org.hibernate.type.EntityType.getIdentifier(EntityType.java:397)
at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:87)
at org.hibernate.param.NamedParameterSpecification.bind(NamedParameterSpecification.java:38)
at org.hibernate.loader.hql.QueryLoader.bindParameterValues(QueryLoader.java:491)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1563)
at org.hibernate.loader.Loader.doQuery(Loader.java:673)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
at org.hibernate.loader.Loader.doList(Loader.java:2213)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104)
at org.hibernate.loader.Loader.list(Loader.java:2099)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:378)
at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338)
at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121)
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
at com.creditprocess.daoimpl.EvaluationDAOImpl.getCrtTotal(EvaluationDAOImpl.java:294)
at com.creditprocess.managerimpl.EvaluationManagerImpl.saveData(EvaluationManagerImpl.java:264)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
at com.sun.proxy.$Proxy28.saveData(Unknown Source)
at EvaluationTest.sendDetails(EvaluationTest.java:150)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.String field com.caja.creditprocess.hbmfiles.Doi_Master.dni to java.lang.String
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)
at java.lang.reflect.Field.get(Field.java:393)
at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:32)
... 62 more
These are my entities
User_Master.java
#Entity
#Table(name="User_Master")
public class User_Master implements Serializable{
#Id
#Column(name="User_master_id")
private String user_master_id;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name="num")
private Number num;
}
Number.java
#Entity
#Table(name="Number")
public class Number implements Serializable{
#Id
#Column(name="num")
private String num;
}
If you are using conditional statement then you have to define some condition after where so here I think You are mission your Entity Variable (num) reference....
public double getDataFromDb(String num) {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
double result=0;
Query getSumquery=(Query)session.createQuery("select sum(u.amount) from User_Master u where u.num =:num");
getSumquery.setParameter("num",num);
List list =getSumquery.list();
result=(double) list.get(0);
tx.commit();
}
While using reflection, I also faced the same problem and the mistake I have done was instead of writing:
Arrays.asList(object.getClass().getDeclaredFields()).forEach(field -> {
field.setAccessible(true);
try {
System.out.pringln(String.valueOf(field.get(object)));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
});
I wrote:
Arrays.asList(object.getClass().getDeclaredFields()).forEach(field -> {
field.setAccessible(true);
try {
System.out.pringln(String.valueOf(field.get(object.getField())));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
});
meaning to say that I tried to get objects field while giving its value as an argument.

Tinkerpop frames: Cannot change the schema while a transaction is active

I'm testing Tinkerpop frames. I have a relationship similar to Person Knows Person but everytime I test my code it gives me this error
com.orientechnologies.orient.core.exception.OSchemaException: Cannot change the schema while a transaction is active. Schema changes are not transactional
at com.orientechnologies.orient.core.metadata.schema.OSchemaShared.saveInternal(OSchemaShared.java:956)
at com.orientechnologies.orient.core.metadata.schema.OSchemaShared.releaseSchemaWriteLock(OSchemaShared.java:751)
at com.orientechnologies.orient.core.metadata.schema.OSchemaShared.doCreateClass(OSchemaShared.java:385)
at com.orientechnologies.orient.core.metadata.schema.OSchemaShared.createClass(OSchemaShared.java:314)
at com.orientechnologies.orient.core.metadata.schema.OSchemaProxy.createClass(OSchemaProxy.java:77)
at com.tinkerpop.blueprints.impls.orient.OrientElement$1.call(OrientElement.java:469)
at com.tinkerpop.blueprints.impls.orient.OrientElement$1.call(OrientElement.java:465)
at com.tinkerpop.blueprints.impls.orient.OrientBaseGraph.executeOutsideTx(OrientBaseGraph.java:1658)
at com.tinkerpop.blueprints.impls.orient.OrientElement.checkForClassInSchema(OrientElement.java:465)
at com.tinkerpop.blueprints.impls.orient.OrientEdge.getClassName(OrientEdge.java:474)
at com.tinkerpop.blueprints.impls.orient.OrientEdge.createDocument(OrientEdge.java:511)
at com.tinkerpop.blueprints.impls.orient.OrientEdge.convertToDocument(OrientEdge.java:441)
at com.tinkerpop.blueprints.impls.orient.OrientEdge.setProperty(OrientEdge.java:314)
at com.tinkerpop.frames.annotations.PropertyAnnotationHandler.processElement(PropertyAnnotationHandler.java:34)
at com.tinkerpop.frames.annotations.PropertyAnnotationHandler.processElement(PropertyAnnotationHandler.java:11)
at com.tinkerpop.frames.FramedElement.invoke(FramedElement.java:89)
at com.sun.proxy.$Proxy7.setWeight(Unknown Source)
at com.spicegraph.test.domain.test.DbTest.addNewStuffToDb(DbTest.java:52)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
I'm using OrientDb as the graph provider. What could have possible gone wrong?
Here is my code:
public interface Ingredient extends VertexFrame{
#Property("name")
public String getName();
#Property("name")
public void setName(String name);
#Adjacency(label="usedwith", direction=Direction.BOTH)
public Iterable<Ingredient> getUsedWithIngredient();
#Adjacency(label = "usedwith")
public Ingredient addUsedWithNewIngredient();
#Incidence(label = "usedwith")
public UsedWithEdge addUsedWithIngredient(final Ingredient person);
#Adjacency(label = "usedwith")
public void removeUsedWithIngredient(final Ingredient person);
#Incidence(label = "usedwith")
public void removeUsedWith(final UsedWithEdge usedWith);
}
public interface UsedWithEdge extends EdgeFrame {
#Property("weight")
public void setWeight(int weight);
#Property("weight")
public int getWeight();
#OutVertex
Ingredient getOutIngredient();
#InVertex
Ingredient getInIngredient();
}
and this is a snippet of the test case
Ingredient v1=framedGraph.addVertex(null, Ingredient.class);
Ingredient v2=framedGraph.addVertex(null, Ingredient.class);
v1.setName("cumin");
v1.setConservAndStoring("conservation yearly");
v1.setPrepAndUse("prep prep ");
v2.setName("cinnamon");
v2.setAbout("about is about");
v2.setConservAndStoring("conservation is daily");
UsedWithEdge edge=v2.addUsedWithIngredient(v2);
edge.setWeight((1)); // << error is thrown here !!
framedGraph.getBaseGraph().commit();
This is an OrientDb problem. I used OrientGraphNoTx
OrientGraphNoTx graph=new OrientDbGenericDao().graphInstance();
FramedGraphFactory factory = new FramedGraphFactory(); // make sure you reuse the factory when creating new framed graphs.
framedGraph = factory.create(graph); // wrap the base graph
and it worked pretty well.

JPA persist fails with new compound key existing relation entities

I'm using:
Spring framework version: 3.2.2.RELEASE
hibernate version: 4.3.0.CR1
spring-data-jpa: 1.3.1.RELEASE
I have following classes:
Client
ClientInfo
Service
Each Client can have [0, N] ClientInfos (one-to-many). Each ClientInfo can have [0, N] Services. And for each ClientInfo-Service 'joint' I have an extra 'description' -field to describe the relationship. The 'joint'-class is called:
ClientInfoService
An example of resulting data structure:
Client
ClientInfo
ClientInfoService
Service
Description
ClientInfoService
Service
Description
ClientInfoService
Service
Description
Here are the codes for the classes:
#Entity
public class Client {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
...
#OneToMany(mappedBy = "client", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<ClientInfo> infos = new HashSet<ClientInfo>();
public Set<ClientInfo> getInfos() {
return infos;
}
public void setInfos(Set<ClientInfo> infos) {
this.infos.clear();
this.infos.addAll(infos);
for (Iterator<ClientInfo> iterator = infos.iterator(); iterator.hasNext();) {
ClientInfo item = iterator.next();
// update client relation to ClientInfo item because it is not necessarily up-to-date with the given input data
item.setClient(this);
}
}
}
#Entity
public class ClientInfo {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
...
#ManyToOne
#JoinColumn(name = "client_id", nullable = false)
private Client client;
#OneToMany(mappedBy = "clientInfoService.client", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<ClientInfoService> services = new HashSet<ClientInfoService>();
public Set<ClientInfoService> getServices() {
return services;
}
public void setServices(Set<ClientInfoService> services) {
this.services.clear();
this.services.addAll(services);
for (Iterator<ClientInfoService> iterator = services.iterator(); iterator.hasNext();) {
ClientInfoService item = iterator.next();
// update client info relation to ClientInfoService item because it is not necessarily up-to-date with the given input data
item.getClientInfoService().setClientInfo(this);
}
}
}
#Entity
public class Service {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
...
#OneToMany(mappedBy = "clientInfoService.service", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<ClientInfoService> infoServices = new HashSet<ClientInfoService>();
#JsonIgnore
public Set<ClientInfoService> getInfoServices() {
return infoServices;
}
public void setInfoServices(Set<ClientInfoService> infoServices) {
this.infoServices.clear();
this.infoServices.addAll(infoServices);
for (Iterator<ClientInfoService> iterator = infoServices.iterator(); iterator.hasNext();) {
ClientInfoService item = iterator.next();
// update service relation to ClientInfoService item because it is not necessarily up-to-date with the given input data
item.getClientInfoService().setService(this);
}
}
}
#Entity
#Table(name = "clientInfo_service")
public class ClientInfoService {
#EmbeddedId
private ClientInfoServiceAssociationId clientInfoService;
#Column(name = "description", nullable = true, length = 200)
private String description;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public ClientInfoServiceAssociationId getClientInfoService() {
return clientInfoService;
}
public void setClientInfoService(ClientInfoServiceAssociationId clientInfoService) {
this.clientInfoService = clientInfoService;
}
#Override
public int hashCode() {
if (this.clientInfoService != null) {
return this.clientInfoService.hashCode();
} else {
return 0;
}
}
#Embeddable
public class ClientInfoServiceAssociationId implements Serializable {
#ManyToOne
#JoinColumn(name = "clientInfo_id", nullable = false)
private ClientInfo clientInfo;
#ManyToOne
#JoinColumn(name = "service_id", nullable = false)
private Service service;
#JsonIgnore
public ClientInfo getClientInfo() {
return clientInfo;
}
public void setClientInfo(ClientInfo clientInfo) {
this.clientInfo = clientInfo;
}
public Service getService() {
return service;
}
public void setService(Service service) {
this.service = service;
}
#Override
public boolean equals(Object obj) {
ClientInfoServiceAssociationId id = (ClientInfoServiceAssociationId) obj;
boolean cond = false;
boolean serv = false;
if (id.clientInfo != null && this.clientInfo != null && id.clientInfo.getId() == this.clientInfo.getId()) {
cond = true;
}
if (id.service != null && this.service != null && id.service.getId() == this.service.getId()) {
serv = true;
}
return cond && serv;
}
#Override
public int hashCode() {
int ret = 0;
if (this.clientInfo != null && this.clientInfo.getId() != null) {
ret += this.clientInfo.getId();
}
if (this.service != null) {
ret += this.service.getId();
}
return ret;
}
}
Everything works perfectly when saving clients with new infos without existing services. The problem case with this setup is:
Save client data with a new info (id: null) with links to existing services.
Following exception comes when calling saveAndFlush():
WARN : org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: -177, SQLState: 23503
ERROR: org.hibernate.engine.jdbc.spi.SqlExceptionHelper - integrity constraint violation: foreign key no parent; FK_L5435O51W7YGX5N3NEJ84GN9V table: CLIENTINFO_SERVICE
ERROR: fi.loikka.nursebuddy.controller.GlobalControllerExceptionHandler - GENERAL ERROR!
org.springframework.orm.jpa.JpaSystemException: org.hibernate.exception.ConstraintViolationException: could not execute statement; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:321)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:403)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:58)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:163)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.data.jpa.repository.support.LockModeRepositoryPostProcessor$LockModePopulatingMethodIntercceptor.invoke(LockModeRepositoryPostProcessor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.sun.proxy.$Proxy90.saveAndFlush(Unknown Source)
at fi.myCompany.component.update(ClientServiceImpl.java:130)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:64)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.sun.proxy.$Proxy92.update(Unknown Source)
at fi.myCompany.component2.updateClient(ClientController.java:107)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:849)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:691)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:66)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:770)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:168)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:136)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at fi.myCompany.security.TokenFilter.doFilterInternal(TokenFilter.java:66)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:136)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:134)
at fi.myCompany.component.Test.addClientInfoWithService(ClientControllerTest.java:426)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:264)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:124)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray2(ReflectionUtils.java:208)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:159)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:87)
at org.apache.maven.plugin.surefire.InPluginVMSurefireStarter.runSuitesInProcess(InPluginVMSurefireStarter.java:83)
at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeProvider(AbstractSurefireMojo.java:793)
at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeAfterPreconditionsChecked(AbstractSurefireMojo.java:703)
at org.apache.maven.plugin.surefire.AbstractSurefireMojo.execute(AbstractSurefireMojo.java:631)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1770)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1684)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1690)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1345)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:241)
at com.sun.proxy.$Proxy76.flush(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.flush(SimpleJpaRepository.java:397)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.saveAndFlush(SimpleJpaRepository.java:365)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:333)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:318)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
... 125 more
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:74)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:190)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:61)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3123)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3586)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:103)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:453)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:345)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:350)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:56)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1167)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1342)
... 145 more
Caused by: java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: foreign key no parent; FK_L5435O51W7YGX5N3NEJ84GN9V table: CLIENTINFO_SERVICE
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.fetchResult(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.executeUpdate(Unknown Source)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:187)
... 155 more
Caused by: org.hsqldb.HsqlException: integrity constraint violation: foreign key no parent; FK_L5435O51W7YGX5N3NEJ84GN9V table: CLIENTINFO_SERVICE
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.Constraint.getException(Unknown Source)
at org.hsqldb.Constraint.checkInsert(Unknown Source)
at org.hsqldb.StatementDML.performIntegrityChecks(Unknown Source)
at org.hsqldb.StatementDML.insertSingleRow(Unknown Source)
at org.hsqldb.StatementInsert.getResult(Unknown Source)
at org.hsqldb.StatementDMQL.execute(Unknown Source)
at org.hsqldb.Session.executeCompiledStatement(Unknown Source)
at org.hsqldb.Session.execute(Unknown Source)
... 158 more
Test case
#Test
#DatabaseSetup(value = "clientcontroller/clientcontrollertestdata_client_with_infos.xml", type = DatabaseOperation.CLEAN_INSERT)
#ExpectedDatabase(value = "clientcontroller/clientcontrollertestdata_client_add_infos_after.xml", assertionMode = DatabaseAssertionMode.NON_STRICT)
public void addClientInfoWithService() throws Exception {
datasource.getConnection().prepareStatement("SET DATABASE REFERENTIAL INTEGRITY TRUE").execute();
Client client = createTestClient( ...);
HashSet<ClientInfo> infos = new HashSet<ClientInfo>();
ClientInfo info1 = new ClientInfo( … );
info1.setId(1l);
Service service1 = new Service( … );
service1.setId(1l);
ClientInfo info2 = new ClientInfo( … );
ClientInfoServiceAssociationId compoundKey = new ClientInfoServiceAssociationId();
compoundKey.setClientInfo(info2);
compoundKey.setService(service1);
ClientInfoService clientInfoNew = new ClientInfoService();
clientInfoNew.setDescription("new description");
clientInfoNew.setClientInfoService(compoundKey);
HashSet<ClientInfoService> set = new HashSet<ClientInfoService>();
set.add(clientInfoNew);
info2.setServices(set);
service1.setInfoServices(set);
infos.add(info1);
infos.add(info2);
client.setInfos(infos);
String resultJSON = jsonConverter.convertToJSON(client);
mockMvc.perform(put("/clients/1").header("headertoken", this.token).content(resultJSON).contentType(MediaType.APPLICATION_JSON)).andExpect(
status().isNoContent());
}
What could be the problem? Something in my entity definions?

How to handle Bean Validation Exceptions

I have a class according to:
#Entity
public class Car {
#Id
#GeneratedValue
private Long id;
#NotNull
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "OWNER_ID")
private Owner owner;
#NotNull()
#Column(nullable = false)
private String make;
#NotNull()
#Column(nullable = true)
private String model;
#Column(nullable = false)
private String gears;
// More fields
Say I am trying to percist the object and one field, make field for instance, is null which is not supposed to be. Following exceptions is thrown:
WARNING: EJB5184:A system exception occurred during an invocation on EJB CarEJB, method: public se.while_se.domain.Car se.while_se.business.CarEJB.createCar(se.while_se.domain.Car)
Sep 09, 2012 12:37:37 PM com.sun.ejb.containers.BaseContainer postInvoke
WARNING:
javax.ejb.EJBException
at com.sun.ejb.containers.BaseContainer.processSystemException(BaseContainer.java:5215)
at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5113)
at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4901)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2045)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1994)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:222)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
at $Proxy137.createCar(Unknown Source)
at se.while_se.business.__EJB31_Generated__CarEJB__Intf____Bean__.createCar(Unknown Source)
at test.CarTest.populate(CarTest.java:197)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:45)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)
Caused by: javax.validation.ConstraintViolationException: Bean Validation constraint(s) violated while executing Automatic Bean Validation on callback event:'prePersist'. Please refer to embedded ConstraintViolations for details.
What I would like to do is to find a best practice to validate the entity before persist it in the database. Sure, I could implement a help method inside the entity class something like:
public boolean validate() {
if(owner == null) {
return false;
}
if(make == null) {
return false;
}
if(model == null) {
return false;
}
return true;
}
But that does not feel as the right approach. Can you please guide me?
Best regards
You can and should validate the entity before persisting like this and return an appropriate error:
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<Car>> constraintViolations = validator.validate(myCar);
if (constraintViolations.size() > 0) {
Set<String> violationMessages = new HashSet<String>();
for (ConstraintViolation<T> constraintViolation : constraintViolations) {
violationMessages.add(constraintViolation.getPropertyPath() + ": " + constraintViolation.getMessage());
}
throw new RuntimeException("Car is not valid:\n" + StringUtils.join(violationMessages, "\n"));
}

Categories

Resources