I'm trying to see if I can use Hibernate to access a database for which I already have some tools in perl, PHP and Java with ad-hoc JDBC. I'm getting this error when I read a few mapped objects from a certain table and then commit the transaction:
Code:
Exception in thread "main" org.hibernate.HibernateException: identifier of an instance of com.lmert.learnhib.CD was altered from 80 to 80
at org.hibernate.event.def.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:58)
at org.hibernate.event.def.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:157)
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:113)
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:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.lmert.learnhib.Main.main(Main.java:55)
I get this when from the following code (when args[1] has the value "from CD"):
Code:
Session session = getSession();
session.beginTransaction();
List l = session.createQuery(args[1]).list();
int i;
System.out.println(args[1]);
System.out.println("--");
for (i=0;i<l.size();i++) {
System.out.println(l.get(i));
}
System.out.println("--");
System.out.println(l.size()+" rows");
session.getTransaction().commit();
I have two tables in a MySQL database mapped to two entity classes. The relevant parts of the tables are as if they had been defined as follows:
Code:
CREATE TABLE CDs (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
artist VARCHAR(100),
title VARCHAR(100)
);
CREATE TABLE CD_tracks (
id INT NOT NULL, -- this would be a foreign key, except that these are MyISAM tables
trackNo INT NOT NULL,
trackArtist VARCHAR(100),
trackTitle VARCHAR(100),
PRIMARY KEY(id,trackNo)
);
I'm using the following mapping file:
Code:
<hibernate-mapping>
<class name="com.lmert.learnhib.CD" table="CDs" >
<id column="id" name="id"
type="short" unsaved-value="0" access="field" >
<generator class="identity" />
</id>
<list name="tracks" access="field" table="CD_tracks" >
<key column="id" not-null="true" />
<list-index
column="trackNo"
base="1" />
<composite-element class="com.lmert.learnhib.CDTrack" >
<parent name="cd" />
<property name="trackTitle" type="string" access="field" />
<property name="trackArtist" type="string" access="field" />
</composite-element>
</list>
<property name="artist" type="java.lang.String" access="field" />
<property name="title" type="java.lang.String" access="field" />
</class>
</hibernate-mapping>
My classes are as follows:
Code:
public class CD {
/** An ID number in our collection. */
private int id;
private String artist;
private String title;
private List<CDTrack> tracks = new java.util.ArrayList();
/** The ID is read-only to user code. */
public int getId() {
return id; }
public String getTitle() {
return title; }
public void setTitle(String title) {
this.title=title; }
public String getArtist() {
return artist; }
public void setArtist(String artist) {
this.artist=artist; }
public int hashCode() {
return id;
}
public String toString() {
return "CD#"+id+" \""+title+"\" ("+tracks.size()+" tracks)";
}
}
public class CDTrack implements Serializable {
private CD cd;
private int trackNo;
private String trackTitle;
private String trackArtist;
private void setCd(CD cd) {
this.cd = cd;
}
private CD getCd() {
return cd;
}
public CD getDisc() {
return cd;
}
public String getTitle() {
return trackTitle; }
public String getArtist() {
return trackArtist; }
public void setTitle(String title) {
trackTitle= title; }
public void setArtist(String artist) {
trackArtist= artist; }
}
So... what am I doing wrong? I didn't see this error when I was mapping just a single table (different class); I only see it (so far) when I try to map two tables to two classes, one of which is a composite element. (I also tried this with a one-to-many association, but couldn't figure out the right XML syntax to use.)