Dear Sir/ Madam,
I have MessageTO object which has a set of receivers, originally of the type PersonTO objects, but wrapped in CompositeMessageReceiverTO because there is a many to many relationship between MessageTOs and PersonTOs and I should set a date (the date each receiver gets the message) property( which is nullable) in the relationship table so I have to map the relationship in a composite element. On the other hand, I have a business constraint that each Message should be delivered to each receiver only once, so I defined a unique constaint named "GAM.AK_MESSAGE_DEPT_PERSO_CORT_MES" on the id of MessageTO and the id of PersonTO. Initially the viewDate of a receiver is null, when he loads the message to view the viewDate should be set, but the unique constraint is violated in practice. It is because of that the query generated to delete the childs of the message contains the condition "... VIEW_DATE=null ", so it can not find the receiver to delete and tries to insert it again, and violates the unique constraint!
sincerely,
Hibernate version:
2.1.6
Mapping documents:
<class name="MessageTO"
table="CORT_MESSAGE"
>
....
<set name="receivers"
lazy="true"
inverse="false"
cascade="all"
table="CORT_MESSAGE_RECEIVER"
outer-join="auto" >
<key column="MSR_MSG_ID"/>
<composite-element class="CompositeMessageReceiverTO">
<many-to-one name= "receiver"
class="PersonTO"
not-null="true"
column="MSR_PER_ID"
/>
<property
name ="viewDate"
type="java.sql.Timestamp"
column="MSR_VIEW_DATE"
not-null="false"
/>
</composite-element>
</set>
...
</class>
Code between sessionFactory.openSession() and session.close():
// There is a Message in DB the id of which is 10 and the viewDate properties of its receivers are null.
...
message = (MessageTO) session.load(MessageTO.class, new Integer(10))
Hibernate.initialize(message.getReceivers());
Set receivers = message.getReceivers();
if ((receivers != null) && (receivers.size() != 0)) {
Iterator iter = receivers.iterator();
while (iter.hasNext()) {
CompositeMessageReceiverTO rcvr = (CompositeMessageReceiverTO) iter.next();
if (rcvr.getReceiver().getId().intValue() == 20 ) {
rcvr.setViewDate(new Date(System.currentTimeMillis()));
break;
}
}
}
session.flush();
...
Full stack trace of any exception that occurs:
Mar 9, 2005 10:42:58 AM net.sf.hibernate.JDBCException <init>
SEVERE: Could not execute JDBC batch update
java.sql.BatchUpdateException: ORA-00001: unique constraint (GAM.AK_MESSAGE_DEPT_PERSO_CORT_MES) violated
at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:380)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:8768)
at com.evermind.sql.FilterStatement.executeBatch(FilterStatement.java:410)
at com.evermind.sql.FilterStatement.executeBatch(FilterStatement.java:410)
at com.evermind.sql.FilterStatement.executeBatch(FilterStatement.java:410)
at net.sf.hibernate.impl.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:54)
at net.sf.hibernate.impl.BatcherImpl.executeBatch(BatcherImpl.java:126)
at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2421)
at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2374)
at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2240)
at gampooya.cor.ejb.MessageEJB.getMessageByPId(MessageEJB.java:129)
at MessageLocal_StatelessSessionBeanWrapper348.getMessageByPId(MessageLocal_StatelessSessionBeanWrapper348.java:747)
Name and version of the database you are using:
Database: Oracle 10g
Application Server: OC4J
The generated SQL (show_sql=true):
delete from CORT_MESSAGE_RECEIVER where MSR_MSG_ID=? and MSR_PER_ID=? and MSR_VIEW_DATE=? and M
SR_INBOX=?
insert into CORT_MESSAGE_RECEIVER (MSR_MSG_ID, MSR_PER_ID, MSR_VIEW_DATE, MSR_INBOX) values (?,
?, ?, ?)
Debug level Hibernate log excerpt:
|