Hibernate 中One To One的用法

我在Github上面写了一个例子,用于展示Hibernate中OneToOne的用法:

https://github.com/liweinan/javaee

可以签出这个代码,然后执行maven打包:

mvn package


然后部署在AS7里面。注意在部署之前要修改一下AS7的数据库配置:

jboss-as-7.1.1.Final/standalone$ vi configuration/standalone.xml 


            <datasources>
                <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
                    <connection-url>jdbc:h2:/usr/local/db/h2db</connection-url>
                    <driver>h2</driver>
                    <security>
                        <user-name>sa</user-name>
                        <password>sa</password>
                    </security>
                </datasource>


这样,H2会生成数据库文件至/usr/local/db/h2db,方便调试。

核心代码是User及Address。User和Address是一对一的关系,此外,Address的主键要求与User保持一致,而User的主键由Hibernate负责生成UUID:

package net.bluedash.model.sandbox.onetoone;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.io.Serializable;

/**
 * 11 11 2012
 *
 * @author [url=mailto:[email protected]]Weinan Li[/url]
 */
@Entity
@Table(name = "onetoone_user")
public class User implements Serializable {
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    private String id;

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "user")
    @PrimaryKeyJoinColumn
    private Address contactAddress;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Address getContactAddress() {
        return contactAddress;
    }

    public void setContactAddress(Address contactAddress) {
        this.contactAddress = contactAddress;
    }
}


package net.bluedash.model.sandbox.onetoone;

import org.hibernate.annotations.*;

import javax.persistence.*;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.io.Serializable;

/**
 * 11 11 2012
 *
 * @author [url=mailto:[email protected]]Weinan Li[/url]
 */
@Entity
@Table(name = "onetoone_address")
public class Address implements Serializable {

    @Id
    @GeneratedValue(generator = "foreign")
    @GenericGenerator(name = "foreign", strategy = "foreign", parameters = @org.hibernate.annotations.Parameter(name = "property", value = "user"))
    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @OneToOne
    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}


注意上面的Hibernate与JPA标记的混用。Hibernate的扩展功能是非常强大的,可以帮助我们生成Address的主键并与User保持一致。

在AS7里面部署项目:



部署成功的话,可以看到数据库被生成了:



进到H2的Console可以看看生成的数据库表结构:

Hibernate 中One To One的用法_第1张图片

需要注意的是SeedImporter中的代码:

        {
            net.bluedash.model.sandbox.onetoone.Address address
                    = new net.bluedash.model.sandbox.onetoone.Address();
            net.bluedash.model.sandbox.onetoone.User user
                    = new net.bluedash.model.sandbox.onetoone.User();

            user.setContactAddress(address);
            address.setUser(user);

            em.persist(user);
            log.info("ONETOONE_USER ID: " + user.getId());
            log.info("ONETOONE_ADDRESS ID: " + address.getId());
        }


其中这行非常重要:

            address.setUser(user);


Hibernate需要知道user的主键,才能将user的主键赋给address,从而保证@PrimaryKeyJoinColumn的约定条件,即User与Address保证主键一致。



你可能感兴趣的:(Hibernate)