【发布时间】:2015-09-01 14:40:53
【问题描述】:
我有以下实体
@Entity
@Table(name = "VEHICLE")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public final class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "VEHICLE_ID")
private int vehicleId;
@Column(name = "MANUFACTURER")
private String manufacturer;
@ManyToOne
@JoinColumn(name = "personId")
private Person person;
//private constructor
private Vehicle() { }
//getters and setters
}
@Entity
@Table(PERSON)
public final class Person {
@Id
@Column(name = "PERSON_ID")
int personId;
String name;
@OneToMany(mappedBy = "person", cascade = CascadeType.ALL)
List<Vehicle> vehicles = new ArrayList<>();
//constructor is private
private Person() {
}
//getters and setters
}
这是我的测试课
public class TestClass {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("vehiclePU");
EntityManager entityManager = emf.createEntityManager();
Person person = entityManager.find(Person.class, 0);
System.out.println("person = " + person);
person.getVehicles().forEach(System.out::println);
emf.close();
}
}
我的问题是
- 为什么它允许将实体声明为 final 并且使用私有的无 arg 构造函数,因为根据 JPA 规范这是不允许的?
- 我知道,对于延迟加载,hibernate 使用代理对象,而代理对象只不过是实体的子类,但是由于这里两个实体都被声明为 final,它如何允许它们被子类化?
我也想知道延迟加载是如何工作的? Hibernate默认使用哪个代理库,我们如何知道它使用的是哪个库?
我正在使用 Hibernate 5 和 JPA 2.1。
【问题讨论】:
-
JPA 规范说......为了可移植性,默认构造函数不应该是私有的。仅此而已,如果实现要支持私有,则可以,但用户在其他实现中不能依赖它。 CLASS 可以是最终的。字段/方法不能...为了可移植性。
-
@NeilStockton 如何允许代理和延迟加载?
-
因为我不使用 Hibernate 并且这是 Hibernate 特定的选项,所以其他人可以回答。并非所有实现都使用“代理”,有些使用包装器,并通过字节码增强来检测此类情况。
-
@NeilStockton 你能分享你找到 jpa Spec 的链接吗?