JPA Lazy加载适用于最终实体和私有构造函数

时间:2015-09-01 14:40:54

标签: java hibernate jpa

我有以下实体

@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();


    }
}

我的问题是

  1. 为什么它允许将实体声明为final并且使用private no arg构造函数,因为根据JPA规范,这是不允许的?
  2. 我明白,对于延迟加载,hibernate使用代理对象,而代理对象只不过是实体的子类,但是因为这两个实体都被声明为final它如何允许它们被分类?
  3. 我也想知道延迟加载是如何工作的? Hibernate默认使用哪个代理库,我们怎样才能知道它使用哪个库?

    我正在使用Hibernate 5和JPA 2.1。

1 个答案:

答案 0 :(得分:1)

正如Neil所说:不需要支持私有构造函数的最终类 - 但不是禁止的。

但除了你失去提供者独立性的事实以及任何JPA验证器都会看到警告之外 - 你也会松散延迟加载

您确实谈到了延迟加载,但您的示例使用它。以下内容适用于具有公共或受保护的noargs构造函数的公共非最终Person类:

@ManyToOne(optional = false, fetch = FetchType.LAZY)
private Person person;

但正如fetch的JavaDoc所说:

  

EAGER策略是持久性提供程序运行时的一项要求,必须急切地获取关联的实体。 LAZY策略是对持久性提供程序运行时的暗示。

所以Hibernate不会抱怨错误的LAZY - 但如果有什么东西可以阻止延迟加载,它会默默地忽略它。例如,最终类,或私有无参数构造函数或optional=true(默认值),不带字节码增强。

您可以通过使用不同选项并检查Hibernate日志(检查load命令)并使用vehicle.getPerson().getClass()来查看所有内容。

只要您有延迟加载工作并收到代理类,您就可以看到Hibernate使用的库: Javassist