Hibernate / JPA - Object中的外键索引

时间:2009-07-13 16:06:12

标签: java nhibernate hibernate jpa java-ee

我目前正在研究由没有JPA / Hibernate经验的人创建的100多个Java对象到JPA实体中。它们的对象基于类本身中的外键引用其他对象。所有主要密钥都在数据库之外生成。

例如(仅举例说明)

汽车

@Entity
@Table(name="CAR")
public class Car {

    private Integer id;
    private String name;

    @Id
    @Column(name="CAR_ID")
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }

    @Column(name="CAR_NAME")
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

}

引擎

@Entity
@Table(name="ENGINE")
public class Engine {

    private Integer id;
    private String name;
    private Integer carId;

    @Id
    @Column(name="ENGINE_ID")
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }

    @Column(name="ENGINE_NAME")
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @Column(name="CAR_ID")
    public Integer getCarId() {
        return carId;
    }
    public void setCarId(Integer carId) {
        this.carId = carId;
    }

}

这是架构的样子:

CREATE TABLE CAR(CAR_ID INTEGER NOT NULL PRIMARY KEY,CAR_NAME VARCHAR(255))
CREATE TABLE ENGINE(ENGINE_ID INTEGER NOT NULL PRIMARY KEY,CAR_ID INTEGER,ENGINE_NAME VARCHAR(255))
ALTER TABLE ENGINE ADD FOREIGN KEY (CAR_ID) REFERENCES CAR(CAR_ID) ON DELETE CASCADE ON UPDATE CASCADE

测试代码

    Car c = new Car();
    c.setId(100);
    c.setName("Dodge Intrepid");
    em.persist(c);

    Engine e = new Engine();
    e.setId(999);
    e.setName("V6");
    e.setCarId(c.getId());
    em.persist(e);

    Object entity = em.find(c.getClass(),c.getId());
    em.remove(entity);

因此,Car ID包含对数据库中Engine的引用。丢失延迟加载并不是什么大问题,因为我们使用的是TRANSACTIONAL Entity Manager。我已经对此进行了测试,看起来效果很好。

我遗失了这个明显的问题吗? 我知道它不完全符合JPA / Hibernate规范,但我认为它有效。

2 个答案:

答案 0 :(得分:3)

您丢失的主要内容是轻松浏览对象图,而无需通过数据访问层始终按ID显式获取关联对象。我理解你不愿意将所有对象ID转换为对象引用,但从长远来看,你可能最好不要进行投资。通过继续您当前的设计,您将最终编写大量额外的数据访问代码,以便在每次需要导航关联时获取相关对象。此外,当对象未在数据库中持久存在时(例如,在构建新对象图或单元测试时),将使对象关系建模变得更加困难。你也放弃了级联(传递)保存和更新。

简而言之,我认为从长远来看,你的系统将更难以维护,除非你解决这个设计问题,否则导航对象图将会非常尴尬。

答案 1 :(得分:1)

没有任何映射关系会使您在HQL查询或条件中几乎不可能有任何联接。一个简单的Select将起作用,但你无法做到

from Engine as eng where eng.car.name = 'DODGE'

如果您至少获得编码的主要关系,那么从长远来看,这将使事情变得更加容易。