Thank you for help.
I have two table.One is "parent" ,another is "child"
parent(pid varchar(10),name varchar(10)). pid is primary key
child(cid varchar(10),otherid smallint,name varchar(10)). cid and otherid compose the primary key.And cid is the foreign key to the parent table.(but i have not add the FK in the database,I want hibernate to do it)
Mapping file
1.
Parent.hbm.xml
Code:
<?xml version="1.0" encoding="GB2312"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="Parent" table="parent">
<id
name="pid"
column="pid"
type="string"
unsaved-value="any"
>
<generator class="assigned"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>
2.
Child.hbm.xmlCode:
<?xml version="1.0" encoding="GB2312"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="Child" table="child">
<composite-id unsaved-value="any">
<key-many-to-one name="cid" class="Parent" column="cid" />
<key-property name="otherid" column="otherid" type="integer"/>
</composite-id>
<property name="name" column="name" type="string" />
</class>
</hibernate-mapping>
The persistent class1.
Parent.javaCode:
public class Parent {
public boolean equals(Object o) {
if (this == o)
return true;
if (this.pid == null)
return false;
if (! (o instanceof Parent))
return false;
Parent c = (Parent) o;
return this.pid.equals(c.pid);
}
public int hashCode() {
return this.pid == null ? super.hashCode() : this.pid.hashCode();
}
String pid;
public void setPid(String value) {
this.pid=value;
}
public String getPid() {
return pid;
}
String name;
public void setName(String value) {
this.name=value;
}
public String getName() {
return name;
}
}
2.
Child.javaCode:
import java.io.Serializable;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
public class Child implements Serializable{
String cid;
public void setCid(String value) {
this.cid=value;
}
public String getCid() {
return cid;
}
Integer otherid;
public void setOtherid(String value){
this.otherid=new Integer(value);
}
public Integer getOtherid(){
return this.otherid;
}
public Child(){
}
String name;
public void setName(String value) {
this.name=value;
}
public String getName() {
return this.name;
}
Parent parent;
public void setParent(Parent value){
this.parent=value;
}
public Parent getParent(){
return this.parent;
}
public boolean equals(Object other) {
if ( !(other instanceof Childpk) ) return false;
Childpk castOther = (Childpk) other;
return new EqualsBuilder()
.append(this.getCid(), castOther.getCid())
.append(this.getOtherid(), castOther.getOtherid())
.isEquals();
}
public int hashCode() {
return new HashCodeBuilder()
.append(getCid())
.append(getOtherid())
.toHashCode();
}
}
Test Class
Code:
import net.sf.hibernate.Session;
import net.sf.hibernate.Transaction;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.Query;
import java.util.Iterator;
import java.util.Collection;
import net.sf.hibernate.HibernateException;
import java.util.HashSet;
import java.util.Set;
class CompositeTest{
private static SessionFactory sessions;
public static void main(String[] args) throws Exception{
Session session = HibernateUtil.currentSession();
Transaction tx= session.beginTransaction();
Parent p=new Parent();
p.setPid("c005");
p.setName("Parent01");
Set s=new HashSet();
Child c=new Child();
c.setName("test");
c.setParent(p);
c.setOtherid("2");
s.add(c);
session.save(c);// if this line is deleted,just save parent object
session.save(p);
session.flush();
tx.commit();
HibernateUtil.closeSession();
System.out.println("over");
}
}
Error Message:
信息: starting query cache at region: net.sf.hibernate.cache.QueryCache
net.sf.hibernate.HibernateException: identifier of an instance of Child altered from Child@5aeb to Child@5aeb
at net.sf.hibernate.impl.SessionImpl.checkId(SessionImpl.java:2606)
at net.sf.hibernate.impl.SessionImpl.flushEntity(SessionImpl.java:2429)
at net.sf.hibernate.impl.SessionImpl.flushEntities(SessionImpl.java:2422)
at net.sf.hibernate.impl.SessionImpl.flushEverything(SessionImpl.java:2224)
at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2203)
at CompositeTest.main(CompositeTest.java:41)
Exception in thread "main"