Hibernate 一对一例

来源:互联网 发布:linux lnmp搭建 编辑:程序博客网 时间:2024/04/28 06:05

一对一关联有两种映射方式:一种是使用主键关联,限制两个数据表的主键使用相同的值;另一种是一个外键和一个惟一关键字对应。

下面的例子采用主键关联。一人一个房间。

SQL:
CREATE TABLE user (
  USER_ID varchar(10) NOT NULL default '',
  NAME varchar(16) NOT NULL default '',
  PRIMARY KEY  (USER_ID)
);
CREATE TABLE room (
  ROOM_ID varchar(10) NOT NULL default '',
  ADDRESS varchar(32) NOT NULL default '',
  PRIMARY KEY  (ROOM_ID)
);

User.java:
package ivan.hibernate.one2one;
public class User {
    private long id;
    private String name;
    private Room room;
    ...//Getters and Setters
}

User.hbm.xml:
<hibernate-mapping>
    <class name="ivan.hibernate.one2one.User" table="USER">
        <id name="id" column="USER_ID" unsaved-value="0">
            <generator class="increment"/>
        </id>
        <property name="name">
            <column name="NAME" length="16" not-null="true"/>
        </property>      
        <one-to-one name="room"
                    class="ivan.hibernate.one2one.Room"
                    cascade="all"/>       
    </class>
</hibernate-mapping>

Room.java:
package ivan.hibernate.one2one;
public class Room {
   private long id;
   private String address;
   private User user;
   ...// Getters and Setters
}

Room.hbm.xml:
<hibernate-mapping>
    <class name="ivan.hibernate.one2one.Room" table="ROOM">
   <id name="id" column="ROOM_ID" unsaved-value="0">
            <generator class="foreign">
                <param name="property">user</param>
            </generator>
        </id>
        <property name="address" type="string"/>       
        <one-to-one name="user"
                    class="ivan.hibernate.one2one.User"
                    constrained="true"/>
    </class>
</hibernate-mapping>

hibernate.cfg.xml:
<hibernate-configuration>
   <session-factory>
        <!-- properties -->
        <property name="connection.username">root</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property>
        <property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property>
        <property name="connection.password"></property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>

      <mapping resource="ivan/hibernate/one2one/Room.hbm.xml" />
      <mapping resource="ivan/hibernate/one2one/User.hbm.xml" />  
   </session-factory>
</hibernate-configuration>

Test.java:
package ivan.hibernate.one2one;

import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;

public class Test {
    public static void main(String[] args) throws HibernateException {
        SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
      
        Room room = new Room();
        room.setAddress("China-10-911");      
      
        User user = new User();
        user.setName("bush");
        user.setRoom(room);
        room.setUser(user);
      
        Session session = sessionFactory.openSession();
        Transaction tx= session.beginTransaction();
        session.save(user);
       
        tx.commit();
        session.close();
        sessionFactory.close();
    }
}

运行后,在mysql,hibernate 数据库中可看见 User 表和 Room 表都增加了一条记录。

存在问题:如果 Room 表已经存在某个 id 值的记录,而增加的 User 记录的 id 将会是此 id 值,将会抛出异常:java.sql.BatchUpdateException: Duplicate entry ...。这是因为 Room 的 id 是根据 User 的 id 来的。如果新增加的 id 在 Room 表中已经存在,就会抛出 SQL 异常。您可以试验,上面步骤成功后,只将表 User 清空。这样表 User 的记录 id 自增又会从 1 开始。当重新运行程序时就会抛出异常。

原创粉丝点击