hibernate - 在插入中排除了MapKeyColumn

时间:2016-02-23 23:29:27

标签: java hibernate jpa one-to-many

我在示例应用程序中有两个Entity类:

@Entity
public class Person {
...
  @OneToMany(mappedBy = "owner", cascade= CascadeType.ALL)
  @MapKeyColumn(name="phone_type")
  private Map<String, Phone> phones = new HashMap<String, Phone>();

  public Map<String, Phone> getPhones() {
    return phones;
  }

  public void setPhones(Map<String, Phone> phones) {
    this.phones = phones;
  }
...
}

@Entity
public class Phone {
...
  @ManyToOne
  private Person owner;

  public Person getOwner() {
    return owner;
  }

  public void setOwner(Person owner) {
    this.owner = owner;
  }
...
}

即使我没有在Phone对象中包含phone_type字段,我希望它根据Person类HashMap中的值保存在DB中。 我没有将字段添加到Phone对象中以避免冗余地管理数据 - 因为phone_type已经作为地图中的键出现。

当我尝试持久化Person对象时,我看到hibernate运行不包括phone_type列的插入 - 例如:

insert into person (first_name, last_name, id) values (?, ?, ?)

insert into phone (number, owner_id, id) values (?, ?, ?)

我错过了一些可以工作的东西吗?据我所知,我的例子复制了一个:https://en.wikibooks.org/wiki/Java_Persistence/Relationships#Map_Key_Columns_.28JPA_2.0.29,但我无法真正开始工作。

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

编辑:嗯,我最初通过删除MapKeyColumn(name="phone_type")注释来实现它。有了它,它如上所述表现得很奇怪。我将mappedBy="owner"重新放入,并且phones_KEY(默认情况下名为phones_KEY,没有MapKeyColumn注释)现在位于Phone表中。

create table Phone (id bigint not null, name varchar(255), owner_id bigint, phones_KEY varchar(255), primary key (id))

当我进行插入时,它首先执行两次插入,没有phones_KEY,然后是phones_KEY字段的更新,可能是在一次交易中。

insert into Person (name, id) values (?, ?)

insert into Phone (name, owner_id, id) values (?, ?, ?)

update Phone set phones_KEY=? where id=?

在我看来,它(hibernate 4.3)在将phones_KEY字段命名为phone_type时不应该有问题,但我想它确实存在问题。我不知道该告诉你什么。

更新:我尝试了这个,它解决了上述无法命名phone_type列的问题。我不知道您的表格结构,但这会生成与上面的注释相同的表格结构,这会将phone_Key列放在Phone实体中。

@Entity
public class Person {
    ...
    @OneToMany( mappedBy="owner", fetch=FetchType.EAGER, cascade=CascadeType.ALL)
    private List<Phone> phones;
    ...
}

@Entity
public class Phone {
    ...
    @ManyToOne
    private Person owner;
    private String phone_type;
    ...
}

您会注意到即使Entities不同,创建的表结构也是相同的。在这种情况下,不是将phone_type作为Map密钥,而是使用MapKeyColumn声明名称,而是将其作为名为{{1的字段放在Phone实体中}}。使用OneToMany phone_type代替地图。由于关系是由List专门映射的,因此Map或List都不会影响映射。现在,插入显示owner表中的phone_type插入。

Phone

希望这有帮助。