我目前正在研究由没有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规范,但我认为它有效。
答案 0 :(得分:3)
您丢失的主要内容是轻松浏览对象图,而无需通过数据访问层始终按ID显式获取关联对象。我理解你不愿意将所有对象ID转换为对象引用,但从长远来看,你可能最好不要进行投资。通过继续您当前的设计,您将最终编写大量额外的数据访问代码,以便在每次需要导航关联时获取相关对象。此外,当对象未在数据库中持久存在时(例如,在构建新对象图或单元测试时),将使对象关系建模变得更加困难。你也放弃了级联(传递)保存和更新。
简而言之,我认为从长远来看,你的系统将更难以维护,除非你解决这个设计问题,否则导航对象图将会非常尴尬。
答案 1 :(得分:1)
没有任何映射关系会使您在HQL查询或条件中几乎不可能有任何联接。一个简单的Select
将起作用,但你无法做到
from Engine as eng where eng.car.name = 'DODGE'
如果您至少获得编码的主要关系,那么从长远来看,这将使事情变得更加容易。