如何避免在一对多单向关联中插入和更新查询

时间:2016-02-14 07:23:01

标签: java mysql hibernate hibernate-onetomany

我在one-to-many&之间有一个简单的Employee关系Phone个实体。

我这里有2个问题。

情景1:

@Entity
public class Employee {
    @Id
    @GeneratedValue
    private long id;

    private String firstName;
    private String lastName;
    private double salary;

    @OneToMany
    @JoinColumn(name = "parent_id", referencedColumnName = "id", insertable=false, updatable=false)
    private List<Phone> phones = new ArrayList<Phone>(0);

// Setters & Getter methods

}

Phone.java

@Entity
public class Phone {
    @Id
    private long id;
    private String type;
    private int areaCode;
    private String phoneNumber;

// Setter & Getters

}

现在我创建了员工实例并添加了2部手机。

Employee e1 = new Employee(10,"Bob", "Way",50000);
Phone p1 = new Phone(1,"home",613,"792-0000");
Phone p2 = new Phone(2,"work",613,"896-1234");          
e1.addPhone(p1);
e1.addPhone(p2);

然后在hibernate中,如果我使用下面的代码:

session.save(e1);
session.save(p1);
session.save(p2);

或者我保存phone然后employee

session.save(p1);
session.save(p2);
session.save(e1);

在这两种情况下,Hibernate只运行insert个查询而没有任何update个查询,但foreign key设置为NULL。

mysql> select * from Phone;
+----+----------+-------------+------+-----------+
| id | areaCode | phoneNumber | type | parent_id |
+----+----------+-------------+------+-----------+
|  1 |      613 | 792-0000    | home |      NULL |
|  2 |      613 | 896-1234    | work |      NULL |
|  3 |      416 | 123-4444    | work |      NULL |
+----+----------+-------------+------+-----------+

我该如何解决这个问题?请告诉我错误的地方。

情景2:

现在,如果我对@JoinColumn表中的Employee进行了更改,如下所示:

@JoinColumn(name = "parent_id")

然后Hibernate正在生成**insert**然后update查询以正确映射外键。

Hibernate: insert into Employee (firstName, lastName, salary) values (?, ?, ?)
Hibernate: insert into Phone (areaCode, phoneNumber, type, id) values (?, ?, ?, ?)
Hibernate: insert into Phone (areaCode, phoneNumber, type, id) values (?, ?, ?, ?)
Hibernate: insert into Phone (areaCode, phoneNumber, type, id) values (?, ?, ?, ?)
Hibernate: update Phone set parent_id=? where id=?
Hibernate: update Phone set parent_id=? where id=?

当Hibernate在insert表上运行Employee时,它会自己获得employee id,那么为什么Hibernate运行时会运行额外的update查询通过包含外键值?

在Phone表上插入查询

我理解在update查询中它正在添加外键,但我想知道为什么在Phone表上insert查询本身不能管理它。你能解释一下吗?

场景3:

如果我这样说:

@JoinColumn(name = "OWNER_ID", insertable=false, updatable=false, nullable=false)

然后我得到以下异常:

Exception in thread "main" org.hibernate.PropertyValueException: not-null property references a null or transient value : onetomany.Phone._phones_OWNER_IDBackref

1 个答案:

答案 0 :(得分:0)

You have a Employee and an Phone. 
You'd like to add insertable=false, updatable=false to the @OneToMany relationship with the Employee entity in the Phone entity, simply because it's not the responsibility of the Phone entity to create or update a Employee. It's the other way round.


@Entity
public class Employee {
    @Id
    @GeneratedValue
    private long id;

    private String firstName;
    private String lastName;
    private double salary;

    @OneToMany(mappedBy="person", cascade=CascadeType.ALL)
    private List<Phone> phones = new ArrayList<Phone>(0);

// Setters & Getter methods

}

@Entity
public class Phone {
    @Id
    private long id;
    private String type;
    private int areaCode;
    private String phoneNumber;

    @ManyToOne
    @JoinColumn(name="PHONE_FK")
    @Column(insertable=false, updatable=false)
    private Employee employee;

}