关于java:Hibernate / JPA-对象本身中的外键索引

Hibernate/JPA - Foreign Key Index in Object itself

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

例如(仅作说明)

汽车

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@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;
    }

}

引擎

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@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;
    }

}

以下是该架构的外观:

1
2
3
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

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
    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);

因此,汽车ID在数据库中保存了对引擎的引用。丢失延迟加载并不重要,因为我们正在使用事务实体管理器。我已经对此进行了测试,它似乎可以正常工作。

我是否缺少与此相关的任何明显问题?我知道它不完全符合JPA / Hibernate规范,但我认为它可以工作。


您丢失的主要事情是轻松浏览对象图,而不必始终通过数据访问层通过ID显式获取关联的对象。我知道您不愿意将所有对象ID都转换为对象引用,但从长远来看,您最好还是进行这项投资。通过继续当前的设计,您将最终编写大量额外的数据访问代码,以在每次需要导航关联时获取相关对象。另外,当对象未持久存储在数据库中时(例如,在构造新的对象图或在单元测试中时),将更难以对对象关系进行建模。您还将放弃级联(可传递)的保存和更新。

简而言之,我认为从长远来看,您的系统将更加难以维护,除非您解决此设计问题,否则导航对象图将非常笨拙。


由于没有任何映射关系,因此几乎不可能在HQL查询或条件中进行任何联接。一个简单的Select将起作用,但您不能执行

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

如果至少您对主要的关系进行了编码,从长远来看,这将使事情变得容易得多。