Tenho uma classe Contato e outra chamada Telefone. Estou tentando fazer com que o hibernate salve automaticamente uma coleção de telefones de uma classe Contato, conforme abaixo:
public class Contato {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private long codigo;
@OneToMany(cascade=CascadeType.ALL)
@JoinTable(name="contato_telefones",
joinColumns=@JoinColumn(name="id_contato"),
inverseJoinColumns=@JoinColumn(name="id_telefone"))
private List<Telefone> colTelefones = new ArrayList<>();
@ElementCollection
@CollectionTable(name="contato_email",
joinColumns = @JoinColumn(name="id_contato"))
private List<String> colEmails = new ArrayList<>();
...
public class Telefone {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private long codigo;
@Column(name="telefone", length=14)
@Length(min=0, max=14, message="O telefone deve ter entre {min} e {max} caracteres")
private String telefone;
@Column(name="DDD")
private int ddd;
@Column(name="local", length=150)
@Length(min=0, max=150, message="O local do telefone deve ter entre {min} e {max} caracteres")
private String local;
Quando realizo um save normal (persist) tenho a seguinte exceção (cria uma instância e insiro nela uma coleção de telefones):
Hibernate: insert into contato_telefones (id_contato, id_telefone) values (?, ?)
2016-06-06 21:54:59,366 DEBUG org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logExceptions:139 - Duplicate entry '10' for key 'UK_el7112shnn5xa8hm6u28yhn04' [n/a]
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '10' for key 'UK_el7112shnn5xa8hm6u28yhn04'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1041)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4190)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4122)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2818)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2157)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2460)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2377)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2361)
at sun.reflect.GeneratedMethodAccessor30.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
at com.sun.proxy.$Proxy36.executeUpdate(Unknown Source)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:56)
at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1204)
at org.hibernate.action.internal.CollectionRecreateAction.execute(CollectionRecreateAction.java:58)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:272)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:264)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:190)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1081)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:315)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:73)
at com.gaspar.escola_jb_dao.principal.ContatoDAO.add_aroundBody1$advice(ContatoDAO.java:118)
at com.gaspar.escola_jb_dao.principal.ContatoDAO.add(ContatoDAO.java:1)
at com.gaspar.escola_jb_dao.principal.ContatoDAO.salvar(ContatoDAO.java:24)
at com.gaspar.escola_jb_dao.principal.ContatoDAOTest.testaAdd(ContatoDAOTest.java:164)
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:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
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)
2016-06-06 21:54:59,374 WARN org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logExceptions:143 - SQL Error: 1062, SQLState: 23000
2016-06-06 21:54:59,375 ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper.logExceptions:144 - Duplicate entry '10' for key 'UK_el7112shnn5xa8hm6u28yhn04'
2016-06-06 21:54:59,376 DEBUG org.hibernate.ejb.AbstractEntityManagerImpl.markAsRollback:1131 - Mark transaction for rollback
2016-06-06 21:54:59,377 DEBUG org.hibernate.engine.transaction.spi.AbstractTransactionImpl.rollback:203 - rolling back
2016-06-06 21:54:59,413 DEBUG org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doRollback:164 - rolled JDBC Connection
2016-06-06 21:54:59,414 DEBUG org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.releaseManagedConnection:126 - re-enabling autocommit
2016-06-06 21:54:59,419 DEBUG com.gaspar.escola_jb_dao.aspects.ExceptionMarker.ajc$before$com_gaspar_escola_jb_dao_aspects_ExceptionMarker$1$7cf7ea01:11 - >>>>>>>>> Escola JbTools - Laurinha (dao) <<<<<<<<<
2016-06-06 21:54:59,420 DEBUG com.gaspar.escola_jb_dao.aspects.DAOAddUpdateAsp.add_aroundBody1$advice:126 - Problemas na persistência
javax.persistence.RollbackException: Error while committing the transaction
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:90)
at com.gaspar.escola_jb_dao.principal.ContatoDAO.add_aroundBody1$advice(ContatoDAO.java:118)
at com.gaspar.escola_jb_dao.principal.ContatoDAO.add(ContatoDAO.java:1)
at com.gaspar.escola_jb_dao.principal.ContatoDAO.salvar(ContatoDAO.java:24)
at com.gaspar.escola_jb_dao.principal.ContatoDAOTest.testaAdd(ContatoDAOTest.java:164)
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:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
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: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: Duplicate entry '10' for key 'UK_el7112shnn5xa8hm6u28yhn04'
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1361)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1289)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:78)
... 28 more
Caused by: org.hibernate.exception.ConstraintViolationException: Duplicate entry '10' for key 'UK_el7112shnn5xa8hm6u28yhn04'
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:74)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129)
at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
at com.sun.proxy.$Proxy36.executeUpdate(Unknown Source)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:56)
at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1204)
at org.hibernate.action.internal.CollectionRecreateAction.execute(CollectionRecreateAction.java:58)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:272)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:264)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:190)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1081)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:315)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:73)
... 28 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '10' for key 'UK_el7112shnn5xa8hm6u28yhn04'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1041)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4190)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4122)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2570)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2731)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2818)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2157)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2460)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2377)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2361)
at sun.reflect.GeneratedMethodAccessor30.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
... 43 more
------ javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: Duplicate entry '10' for key 'UK_el7112shnn5xa8hm6u28yhn04'
org.hibernate.exception.ConstraintViolationException: Duplicate entry '10' for key 'UK_el7112shnn5xa8hm6u28yhn04'
Só dá certo se eu criar uma instância da classe Contato e a salvo, crio cada uma das instâncias da classe Telefone e as persisto no BD e, somente após tudo estar salvo no BD é que consigo alterar a classe Contato inserindo na mesma a coleção de telefones e depois a alterando. Porém o que gostaria é criar uma instância da classe Contato completa (ou seja com a lista de telefones - ainda não salvos) e somente persisti-la no BD (por isso o cascade na anotação).