Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp
[b]Hibernate version:[/b]
3.3.1
[b]Mapping documents:[/b]
[b]Code between sessionFactory.openSession() and session.close():[/b]
rqConfig.addAnnotatedClass(ResvSessionModel.class); // this tells to hibernate how our table look like
rqConfig.addAnnotatedClass(ResvFlowModel.class);
rqConfig.configure(); // this configures hibernate to use our table
// definition via our object class
// Create the table - watch out - this will drop && recreate the
// table every time !!
new SchemaExport(rqConfig).create(true, true);
// Rows are added via Session Factory
SessionFactory rqFactory = rqConfig.buildSessionFactory();
Session rqSession = rqFactory.getCurrentSession();
// Let's add a row - steps
// 1 - begin a DB transation
rqSession.beginTransaction();
// 2 - do your data stuff
ResvSessionModel myObj = new ResvSessionModel();
Long myLong = new Long(100);
myObj.setExpireTime(myLong);
String myStr = new String("Test String RqSession");
myObj.setRqSessionId(myStr);
ResvFlowModel myObj1 = new ResvFlowModel();
myObj1.setBwDL(new Long(10));
myObj1.setBwUL(new Long(20));
myObj1.setIpAddr(new String("haha"));
myObj1.setMcld(new Long(30));
myObj1.setMsdld(new Long(40));
myObj1.setServiceId(new Long(50));
myObj1.setResvSession(myObj);
ResvFlowModel myObj2 = new ResvFlowModel();
myObj2.setBwDL(new Long(10));
myObj2.setBwUL(new Long(20));
myObj2.setIpAddr(new String("haha"));
myObj2.setMcld(new Long(30));
myObj2.setMsdld(new Long(40));
myObj2.setServiceId(new Long(50));
myObj2.setResvSession(myObj);
// 3 - do your SQL request ex: save, update, etc ...
rqSession.saveOrUpdate(myObj);
rqSession.saveOrUpdate(myObj1);
rqSession.saveOrUpdate(myObj2);
// 4 - do a COMMIT to database
rqSession.getTransaction().commit();
// Test cascade delete
rqFactory = rqConfig.buildSessionFactory();
rqSession = rqFactory.getCurrentSession();
rqSession.beginTransaction();
rqSession.delete(myObj);
rqSession.getTransaction().commit();
[b]Full stack trace of any exception that occurs:[/b]
14:57:26,558 DEBUG SQL:111 - delete from resv_session where RowId=?
Hibernate: delete from resv_session where RowId=?
14:57:26,559 DEBUG AbstractBatcher:66 - Executing batch size: 1
14:57:26,561 DEBUG AbstractBatcher:418 - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
14:57:26,562 WARN JDBCExceptionReporter:100 - SQL Error: 1451, SQLState: 23000
14:57:26,562 ERROR JDBCExceptionReporter:101 - Cannot delete or update a parent row: a foreign key constraint fails (`rqtest`.`resv_flow`, CONSTRAINT `FK948353F7DB747064` FOREIGN KEY (`ResvSessionID`) REFERENCES `resv_session` (`RowId`))
14:57:26,564 ERROR AbstractFlushingEventListener:324 - Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:172)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:365)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
at ResvDbMainUnitTest.main(ResvDbMainUnitTest.java:75)
Caused by: java.sql.BatchUpdateException: Cannot delete or update a parent row: a foreign key constraint fails (`rqtest`.`resv_flow`, CONSTRAINT `FK948353F7DB747064` FOREIGN KEY (`ResvSessionID`) REFERENCES `resv_session` (`RowId`))
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1693)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1108)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
... 8 more HibernateException
[b]Name and version of the database you are using:[/b]
MySQL 6.0
[b]The generated SQL (show_sql=true):[/b]
14:57:26,558 DEBUG SQL:111 - delete from resv_session where RowId=?
[b]Debug level Hibernate log excerpt:[/b]
<property name="hibernate.show_sql">
true
</property>
resv_session has a "one-to-many" relationship with resv_flow. I am trying to enable the CascadeType (at least for Remove) such that when I delete a entry in resv_session, the resv_flow is cleared accordingly.
Unfortunately, that seems not to work. The only way is to enable that I could, is to enable manually the Foreign Key in resv_flow to have On Delete to Cascade in MySql via the Admin Gui.
Can I do something with hibernate to overcome this ?!?
Code:
@Entity
@Table(name = "resv_flow")
public class ResvFlowModel
{
// row definitions
private Long rowId; // Id used by Hibernate
private Long mcdld;
private Long msdld;
private String ipAddr;
private Long serviceId;
private Long bwUL;
private Long bwDL;
private ResvSessionModel resvSession; // A Resv Flow belongs to a Resv Session
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "RowId")
public Long getId()
{
return this.rowId;
}
public void setId(Long id)
{
this.rowId = id;
}
@Column(name = "IpAddr", length = 16)
public String getIpAddr()
{
return this.ipAddr;
}
public void setIpAddr(String ip)
{
this.ipAddr = ip;
}
@Column(name = "ServiceId")
public Long getServiceId()
{
return this.serviceId;
}
public void setServiceId(Long sId)
{
this.serviceId = sId;
}
// Definition of the many to one to inform Hibernate to map back to ResvSession
@ManyToOne
@JoinColumn(name = "ResvSessionID")
// Methods to set/get to which Resv Session a Flow belongs to
public ResvSessionModel getResvSession()
{
return this.resvSession;
}
public void setResvSession(ResvSessionModel curResvSession)
{
this.resvSession = curResvSession;
}
}
@Entity
@Table(name = "resv_session")
public class ResvSessionModel
{
// row definitions
private Long rowId; // primary key used by Hibernate
private String rqSid; // Rq Session Id - generated by Diameter stack
private Long expireTime; // Rq Session expiration time - life time
private List<ResvFlowModel> myResvFlows; // defines list of Resv Flows belongs
// to this Resv Session
// primary key - generated by Oracle.
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "RowId")
public Long getRowId()
{
return this.rowId;
}
// Set's the primary key
public void setRowId(final Long dbId)
{
this.rowId = dbId;
}
// Left empty - for now
// Definition of the many to one to inform Hibernate to map back to ResvSession
// Fetch - can be EAGER - but this implies all table to be loaded in memory !!
@OneToMany(cascade = CascadeType.ALL, mappedBy = "resvSession", targetEntity = ResvFlowModel.class, fetch = FetchType.LAZY)
// Get't the Rq Session Flow's
public List<ResvFlowModel> getResvFlowModel()
{
return this.myResvFlows;
}
// Set's the Rq Session Flow's
public void setResvFlowModel(List<ResvFlowModel> curResvFlow)
{
this.myResvFlows = curResvFlow;
}
}