当前位置: 首页 > 知识库问答 >
问题:

JPA延迟加载处理最终实体和私有构造函数

皇甫树
2023-03-14

我有以下实体

@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. 为什么它允许将实体声明为最终实体并且私有无 arg 构造函数,因为根据 JPA 规范这是不允许的?
  2. 我知道对于延迟加载Hibernate使用代理对象,而代理对象只不过是实体的子类,但是由于这里两个实体都声明为最终的,它如何允许它们被子类化?

我也想知道延迟加载是如何工作的?以及Hibernate默认使用哪个代理库,我们如何知道它使用哪个库?

我正在使用Hibernate 5和JPA 2.1。

共有1个答案

蒋联
2023-03-14

正如Neil所说:不需要用私有构造函数支持final类,但这并不是禁止的。

但是除了会失去提供者独立性以及会看到任何JPA验证器的警告之外,还会失去惰性加载。

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

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

但正如 JavaDoc for fetch 所说:

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

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

您可以通过使用不同的选项并检查Hibernatehtml" target="_blank">日志(检查加载命令)以及使用vehicle.getPerson().getClass()来查看所有这些。

一旦你有了延迟加载工作并收到一个代理类,你就可以看到Hibernate使用的库:Jav辅助

 类似资料:
  • 问题内容: 为什么将只有私有构造函数的类标记为final是一个好习惯?我的猜测是,要让其他程序员知道它不能被子类化。 问题答案: 将类定为final具有一些(小的)性能提升,因为JIT编译器可以内联该类的功能。我不知道这是否符合“良好做法”的要求,但是我看到了好处。

  • 问题内容: 假设有一个类,其所有构造函数都声明为private。 例如。: 据我所知,将所有构造函数设为私有类似于将类“ This”声明为 final ,因此无法进行扩展。 但是,我收到的Eclipse消息给我的印象是这是可能的-可以扩展全构造函数私有类。看看这个: 当我尝试使用类似的方法扩展此类时 Eclipse给了我一个错误:“ 隐式超级构造函数This()对于默认构造函数不可见。必须定义一个

  • 假设有一个类,其所有构造函数都声明为private。 如。: 据我所知,将所有构造函数私有化类似于将类“This”声明为final——因此它不能被扩展。 然而,我收到的Eclipse消息给我的印象是这是可能的——一个all constructors私有类可以扩展。看看这个: 当我试图用类似于 Eclipse给我一个错误:“隐式超级构造函数This()对默认构造函数不可见。必须定义显式构造函数。"

  • 问题内容: 我在JPA实体中的延迟加载属性有问题。我读过许多类似的问题,但它们与spring或hibernate有关,并且他们的后代不适用或没有帮助。 该应用程序是在Wildfly应用程序服务器上运行的JEE和JPA2.1。有两个实体,DAO会话bean和servlet将它们放在一起: 当我运行此代码时,它失败并显示: 我对WebLogic / JPA1使用了非常相似的模式,并且运行平稳。任何的想

  • 看了几个网页后,我仍然不明白为什么我的@ElementCollection会急切地加载。我的理解是,默认情况下任何@ElementCollection都应该总是懒洋洋地加载。正如您所看到的,情况并非如此--您将在本文末尾看到控制台的输出。我试图使用@ElementCollection(fetch=fetchType.lazy)注释强制执行惰性加载,但这并没有改变任何事情。有没有人可以解释一下,也可

  • 我正在使用Spring并在“mapper”字段的第一个控制器中遇到问题: 上下文初始化期间遇到异常-取消刷新尝试:org。springframework。豆。工厂UnsatisfiedPendencyException:创建名为“controller”的bean时出错:未满足的依赖项通过字段“mapper”表示;嵌套的异常是org。springframework。豆。工厂BeanCreationE

  • 问题内容: 我以这样一种方式进行了JPA设置:如果我不使用延迟加载,则几乎将加载整个数据库。我也直接在模型上使用序列化,因此有时我需要初始化代理。 我只想在集合上使用延迟加载。急切地获取某些奇异实体的事实就很好了。但是,无论我如何尝试设置集合,我都永远不会得到代理集合,而我总是会得到完全加载的集合。 这是一些示例代码: 所以这里的问题是,当我检查调试器时,答复的persistantBag-list

  • 我正在使用Play Framework v.2.6.3和用于SQL访问的JPA解决方案。 当我在实体上设置FetchType.Lazy时,我会收到以下错误消息: play.api.http。HttpErrorHandlerExceptions$$anon$1:执行异常[[RuntimeException:java.lang.IllegalArgumentException:未能延迟初始化角色集合: