在hibernate中,怎么处理复合主键中的一个字段既作主键又作外键?

时间:2022-08-22 13:37:38
  在hibernate中,怎么处理复合主键中的一个字段既作主键又作外键?
贴子类
public class Post implements Serializable{
private static final long serialVersionUID = 1L;
private java.lang.String postsID;// 贴子ID
private java.lang.String userID;// 用户ID
private java.lang.String subject;// 标题
private java.lang.String content;// 内容
private int backNumber;// 回复数
private int hasNewRead;// 是否有新的留言
private java.util.Date postDate;// 发贴时间
private java.util.Date lastDate;// 最新回贴人的回贴时间
private java.lang.String lastBackUser;// 最后回复人
private int clicknum;// 点数
public Set<Response> responses;// 回复信息
贴子映射文件
<hibernate-mapping >
<class name="com.practiceSystem.model.Post" table="POST" lazy="false">
<id name="postsID"  type="java.lang.String">
<generator class="assigned"/>
</id>
<property name="userID"></property>
<property name="subject"></property>
<property name="content"></property>
<property name="backNumber"></property>
<property name="hasNewRead"></property>
<property name="postDate"></property>
<property name="lastDate"></property>
<property name="lastBackUser"></property>
<property name="clicknum"></property>
<set name="responses" inverse="false" cascade="all">
<key column="POSTSID" />
<one-to-many class="com.practiceSystem.model.Response"/>
</set>
</class>
</hibernate-mapping>

回复类
public class Response {
private ResponsePk responsePk;//回复贴子的主键
private java.lang.String content;// 回复内容
private java.lang.String backUserName;// 回复人
private java.util.Date backDate;// 回日期
private Post Post;// 所回复的贴子
主键类
public class ResponsePk  implements Serializable{
private static final long serialVersionUID = 1L;
public java.lang.String postsId;//贴子ID
public java.lang.String backOrder;// 回复次序
回复映射文件
<hibernate-mapping >
<class name="com.practiceSystem.model.Response" table="RESPONSE">
<composite-id name="responsePk">
<key-property name="postsId" />
<key-property name="backOrder" />
</composite-id>
<property name="content"></property>
<property name="backUserName"></property>
<property name="backDate"></property>
<many-to-one name="Post" column="POSTSID" cascade="all"
class="com.practiceSystem.model.Post" >
</many-to-one>
</class>
</hibernate-mapping>

测试
public static void testresponse(){
SessionFactory session = new Configuration().configure().buildSessionFactory();
ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
Session se = (Session) threadLocal.get();
if (se == null) {
se = session.openSession();
threadLocal.set(se);
}
Transaction transaction = se.beginTransaction();
Query query = se.createQuery("from Response");
List list = query.list();
for (int i = 0; i < list.size(); i++) {
Response response = (Response) list.get(i);
System.out.println(response.getBackUserName() + ":" + response.getContent());
}

Response response = new Response();
response.setBackDate(new Date());
response.setBackUserName("李四2");
response.setContent("测试response2");
ResponsePk pk = new ResponsePk();
pk.setBackOrder("6");
pk.setPostsId("110");
response.setResponsePk(pk);

se.save(response);
transaction.commit();
System.out.println(new Date());
}
报错
严重: Could not synchronize database state with session
org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:254)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1001)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:339)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.practiceSystem.model.test.Client.testresponse(Client.java:108)
at com.practiceSystem.model.test.Client.main(Client.java:25)
Caused by: java.sql.BatchUpdateException: ORA-00957: duplicate column name

at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:367)
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:8738)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:247)
... 9 more

3 个解决方案

#1


将子表的主键做父表的外键不就行了

#2


怎么设置啊,好像子表的主键不能作父表的外键,只能是父表的主键座位子表的外键

#3


这个是子表 EmpSub里面主键的配置(主表的主键做为子表的外键),你换成复合主键的方式试试。
 
<id name="empNo" type="string">
            <column name="EMP_NO" length="6" />
            <generator class="foreign">
                <param name="property">empEmpMst</param>
            </generator>
        </id>

#1


将子表的主键做父表的外键不就行了

#2


怎么设置啊,好像子表的主键不能作父表的外键,只能是父表的主键座位子表的外键

#3


这个是子表 EmpSub里面主键的配置(主表的主键做为子表的外键),你换成复合主键的方式试试。
 
<id name="empNo" type="string">
            <column name="EMP_NO" length="6" />
            <generator class="foreign">
                <param name="property">empEmpMst</param>
            </generator>
        </id>