Hi All,
Currently I use Hibernate 4.1.3. I faced problem when deleting child in one-to-many relationship.
Code:
@Entity
@Table(name="PARENT")
public class Parent {
private Long id;
private Long name;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
@JoinTable(name = "PARENT_CHILD", joinColumns = @JoinColumn(name = "PARENT_ID"), inverseJoinColumns = @JoinColumn(name = "CHILD_ID"))
@Fetch(FetchMode.SUBSELECT)
@OrderColumn(name = "ORDER_IDX", nullable = false)
public List<Child> getChildren() {
return values;
}
...
}
@Entity
@Table(name="CHILD")
public class Child {
private Long id;
private String name;
...
}
Auto generated table:
- PARENT : ID (PK), NAME
- CHILD: ID (PK), NAME
- PARENT_CHILD: PARENT_ID (FK to PARENT), CHILD_ID (FK to CHILD), ORDER_IDX
PK -> PARENT_ID AND ORDER_IDX
UQ -> CHILD_ID
Data:
- PARENT:
ID, NAME
1, PARENT
- CHILD:
ID, NAME
1, one
2, two
3, three
4, four
- PARENT_CHILD
PARENT_ID,CHILD_ID, ORDER_IDX
1, 1, 0
1, 2, 1
1, 3, 2
1, 4, 3
Here is my code to delete child 2:
Code:
Parent p = session.get(Parent.class, 1L);
List<Child> children = p.getChildren();
children.remove(1);
session.update(p);
This is the generated query:
Code:
delete from PARENT_CHILD where PARENT_ID=? and ORDER_IDX=?
<binding parameter [1] as [BIGINT] - 1>
<binding parameter [2] as [INTEGER] - 3>
update PARENT_CHILD set CHILD_ID=? where PARENT_ID=? and ORDER_IDX=?
<binding parameter [1] as [BIGINT] - 2>
<binding parameter [2] as [BIGINT] - 1>
<binding parameter [3] as [INTEGER] - 0>
update PARENT_CHILD set CHILD_ID=? where PARENT_ID=? and ORDER_IDX=?
<binding parameter [1] as [BIGINT] - 3>
<binding parameter [2] as [BIGINT] - 1>
<binding parameter [3] as [INTEGER] - 1>
update PARENT_CHILD set CHILD_ID=? where PARENT_ID=? and ORDER_IDX=?
<binding parameter [1] as [BIGINT] - 4>
<binding parameter [2] as [BIGINT] - 1>
<binding parameter [3] as [INTEGER] - 2>
Exception:
Code:
Exception in thread "main" org.hibernate.exception.ConstraintViolationException: Violation of UNIQUE KEY constraint 'UQ__PARENT_C__F76978E5642941F0'. Cannot insert duplicate key in object 'dbo.PARENT_CHILD'.
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:128)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
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 $Proxy25.executeBatch(Unknown Source)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.performExecution(BatchingBatch.java:110)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.doExecuteBatch(BatchingBatch.java:101)
at org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl.execute(AbstractBatchImpl.java:161)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.executeBatch(JdbcCoordinatorImpl.java:162)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:357)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:278)
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:1214)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:403)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
at com.jcss.main.MainApp.query(MainApp.java:98)
at com.jcss.main.MainApp.main(MainApp.java:69)
Caused by: java.sql.BatchUpdateException: Violation of UNIQUE KEY constraint 'UQ__PARENT_C__F76978E5642941F0'. Cannot insert duplicate key in object 'dbo.PARENT_CHILD'.
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeBatch(SQLServerPreparedStatement.java:1132)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:122)
... 16 more
Can anyone help me to solve this problem?
Thanks