在两个表中具有休眠的主键

时间:2019-09-18 08:30:48

标签: hibernate primary-key nhibernate-mapping

我正在尝试学习Hibernate,并且我有两个彼此相关的课程;人和地址。 Person组成Address对象,并且在db Person表上具有address_id列。

基本上:

1)表人具有以下列:ID,姓名,年龄,address_id 2)表地址包含列:id,街道,城市

我观察到的是当我插入一条记录时,它对Person表使用id = 1,对Address表使用id = 2。因此,它看起来像是从相同序列生成PK。其实一切正常,但是为什么会这样,为什么在地址表中不使用id = 1?

代码如下:

@Entity
public class Person {


    public Person(){

    }

    public Person(String name, int age, Adress adress){
        this.name = name;
        this.age = age;
        this.adress = adress;
    }

    @Id
    @GeneratedValue
    private int id;

    @Column(name = "NAME")
    private String name;

    @Column(name = "AGE")
    private int age;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="address_id")
    private Adress adress;
}

另一个类是:

@Entity
public class Adress {

    @GeneratedValue
    @Id
    private int id;

    @Column(name = "STREET")
    private String street;

    @Column(name = "CITY")
    private String city;


    public Adress(){

    }

    public Adress(String street, String city){
        this.street = street;
        this.city = city;
    }

我将保存方法称为:

  private static void addPerson(SessionFactory sessionFactory){
        Adress adress = new Adress("Wroclawska", "Krakow");
        Person person = new Person("Cemal Inanc", 31, adress);

        Transaction tx = null;
        Session session = null;
        try {
            session= sessionFactory.openSession();
            tx = session.beginTransaction();
            session.save(person);
            tx.commit();
        }
        catch (Exception e){
            tx.rollback();
            System.out.println("Exeception occured");
        }
        finally {
            session.close();
        }
    }

2 个答案:

答案 0 :(得分:4)

由于您使用了默认的生成器策略,因此对于oracle,它是Sequence。

内部会在数据库中创建一个序列并从该序列中获取值。

现在,您要为两个实体获取单独的序列。您需要指定

@SequenceGenerator()

您必须在代码中进行的更改:

对于人实体

@Entity
public class Person {

    @Id
    GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "GeneratorName")
    @SequenceGenerator(name="GeneratorName", sequenceName = "seq1")
    private int id;    
}

对于地址实体

@Entity
public class Adress {

    @Id
    GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "GeneratorName")
    @SequenceGenerator(name="GeneratorName", sequenceName = "seq2")
    private int id;
}

应用这些更改后,您将获得两个ID都从1开始。

答案 1 :(得分:1)

如果未指定序列名称,则默认情况下,Hibernate对alle实体使用相同的序列或表。

如果要使用序列,并且数据库支持,则必须指定生成策略和序列生成器。

@Id
@GeneratedValue(
    strategy = GenerationType.SEQUENCE,
    generator = "sequence-generator"
)
@SequenceGenerator(
    name = "sequence-generator",
    sequenceName = "address_sequence"
)
private int id;

在Hibernate官方文档中了解有关此内容的更多信息: https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#identifiers