I have an enviroment where lots of different threads CONCURRENTLY persists new dialup information. Each new dialup (a RAS-bean) has a ras-message component. Before setting the ras-message component (child) and persisting the RAS-bean (the father), I either save the rasMessage component or load it like:
//Retrieve RAS message component from method
private RasFailMessageBean persistAndRetriveRasFailMessage(..){
List<?> results = query.list();
if (results != null && !results.isEmpty()) {
return (RasFailMessageBean) results.get(0);
} else {
RasFailMessageBean rasMsg = new RasFailMessageBean(code, msg);
getSession().save(rasMsg);
return rasMsg;
}
}
//set component to ras-bean (calls method above)
rasBean.setRasFailMessage(
persistAndRetriveRasFailMessage(rasFailMsgBean.getFailCode(), rasFailMsgBean.getFailMessage()));
//persist
getSession().saveOrUpdate(rasBean);
getSession().flush();
I've also tried to synchronize the method persistAndRetriveRasFailMessage with no luck.
The code above works like 95 times out of hundred. When fail, I get the exception below. What to do?
All help is very appreciated.
Thanks!
Hibernate version:3.2
Name and version of the database you are using: HSQLDB
Hibernate mapping of RAS-bean
This class is a subclass of statisticsbean
/**
* @author qmartek
* @hibernate.joined-subclass table="RAS"
* @hibernate.joined-subclass-key column="STATISTICS_ID"
*/
public class RasBean extends StatisticsBean {
private RasFailMessageBean rasFailMessage = new RasFailMessageBean(-1, "Undefined");
...
/**
* @hibernate.many-to-one column="RAS_FAIL_MESSAGE_ID" cascade="save-update"
* @hibernate.column name="RAS_FAIL_MESSAGE_ID" not-null="true"
* @return Returns the rasFailMessage.
*/
public RasFailMessageBean getRasFailMessage() {
return rasFailMessage;
}
...
}
Hibernate mapping od StatisticsBean
/**
* @hibernate.class table="STATISTICS" lazy="false"
*/
public class StatisticsBean {
...
}
Hibernate mapping od RasFailMessageBean
/**
* @author qmartek
* @hibernate.class table="RAS_FAIL_MESSAGE" lazy="false"
*/
public class RasFailMessageBean {
private int rasFailMessageId = -1;
private String failMessage = null;
private int failCode = -1;
public RasFailMessageBean(){}
/**
* @hibernate.property column="FAIL_CODE"
* @hibernate.column name="FAIL_CODE" unique="true" not-null="true" unsaved-value="undefined"
* @return Returns the failCode.
*/
@Column(name = "FAIL_CODE")
public int getFailCode() {
return failCode;
}
public void setFailCode(int failCode) {
this.failCode = failCode;
}
/**
* @hibernate.property column="FAIL_MESSAGE"
* @hibernate.column name="FAIL_MESSAGE" sql-type="LONGVARCHAR" length="1000"
* @return Returns the message.
*/
@ManyToOne
@JoinColumn(name = "FAIL_MESSAGE")
public String getFailMessage() {
return failMessage;
}
public void setFailMessage(String failMessage) {
this.failMessage = failMessage;
}
/**
* @hibernate.id generator-class="native" column="RAS_FAIL_MESSAGE_ID" unsaved-value="undefined"
* @hibernate.column name="RAS_FAIL_MESSAGE_ID" sql-type="INTEGER"
* @return Returns the rasMessageId.
*/
@Id
@Column (name = "RAS_FAIL_MESSAGE_ID")
public int getRasFailMessageId() {
return rasFailMessageId;
}
public void setRasFailMessageId(int rasFailMessageId) {
this.rasFailMessageId = rasFailMessageId;
}
@Override
public String toString() {
// TODO Auto-generated method stub
if(this.failCode==0){
return "0, No error";
}
return this.failCode + ", " + this.failMessage;
}
}
Full stack trace of any exception that occurs:
006-02-17 11:43:45,505 WARN [util.JDBCExceptionReporter]: SQL Error: -104, SQLState: 23000
2006-02-17 11:43:45,505 ERROR [util.JDBCExceptionReporter]: Unique constraint violation: SYS_CT_71 in statement [insert into RAS_FAIL_MESSAGE (FAIL_CODE, FAIL_MESSAGE, RAS_FAIL_MESSAGE_ID) values (?, ?, null)]
2006-02-17 11:43:45,521 ERROR [hibernate.AssertionFailure]: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
org.hibernate.AssertionFailure: null id in com.ericsson.rgv.platform.database.hibernate.RasFailMessageBean entry (don't flush the Session after an exception occurs)
at org.hibernate.event.def.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:48)
at org.hibernate.event.def.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:140)
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:97)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:195)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:76)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:908)
at sun.reflect.GeneratedMethodAccessor62.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:274)
at $Proxy1.flush(Unknown Source)
at com.ericsson.rgv.platform.database.dao.hibernate.StatisticsDAOHibernate.makePersistent(Unknown Source)
at com.ericsson.rgv.platform.database.actions.AutotestStatisticsAction.perform(Unknown Source)
at com.ericsson.rgv.platform.database.persistence.HibernateThreadFilter.invoke(Unknown Source)
at com.ericsson.rgv.platform.database.persistence.RequestProcessor.processRequest(Unknown Source)
at com.ericsson.rgv.platform.database.persistence.RequestProcessor.processRequest(Unknown Source)
at com.ericsson.rgv.platform.test.AbstractTest$10.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
|