使用Hibernate EntityManager获取映射的超类的实例 [英] Getting An Instance Of A Mapped Superclass With Hibernate EntityManager

查看:86
本文介绍了使用Hibernate EntityManager获取映射的超类的实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在处理Hibernate中的Mapped Superclass时遇到一些问题.我有两个应用程序,产品和制造商共享一个公共库,但彼此之间没有任何直接依赖关系.Common库具有一个抽象的MappedSuperclass(common.domain.Manufacturer),它是基础实体.制造商有一个具体的类,它扩展了Common中的类.产品中没有该类的具体版本.

I'm having some issues dealing with a Mapped Superclass in Hibernate. I have two applications, Product and Manufacturer that share a Common library but otherwise do not have any direct dependencies on each other. The Common lib has an abstract MappedSuperclass (common.domain.Manufacturer) that is the base entity. Manufacturer has a concrete class that extends the class in Common. There is no concrete version of the class in Product.

最初,由于common.domain.Manufacturer没有被识别为实体,我什至无法编译它.我可以通过ORM配置定义实体映射来解决此问题(请参阅:处理休眠有关更多详细信息,请参见映射超类的持久性.尽管确实解决了编译问题,但是不幸的是,我仍然在运行时看到错误.当我在映射的超类上调用entityManager.find()时,它失败并显示以下错误: org.hibernate.InstantiationException:无法实例化抽象类或接口:com.tura.common.domain.Manufacturer

Originally, I was having trouble even getting this to compile since the common.domain.Manufacturer was not being recognized as an entity. I was able to fix that by defining the entity mapping via my ORM config (see: Handling Hibernate Persistence in Mapped Superclass for more details). While that did solve the compilation issues, unfortunately I'm still seeing errors at runtime. When I call entityManager.find() on the mapped superclass it fails with the error: org.hibernate.InstantiationException: Cannot instantiate abstract class or interface: : com.tura.common.domain.Manufacturer

我想也许我可以使用EntityManager.getReference()代替find().只要我实际上不需要除主键以外的任何其他有关制造商的信息,那就行得通.不幸的是,在代码中的一些地方,我需要一些有关制造商的附加信息.一旦我访问除ID以外的任何其他字段,它都会失败,并显示相同的错误.

I thought perhaps I could use entityManager.getReference() instead of find(). That works as long as I don't actually need any information about the Manufacturer other than the primary key. Unfortunately, there are a few places in the code where I need some additional information about the Manufacturer. As soon as I access any field other than the Id it fails with the same error.

我现在可以看到三个选项,但是它们都带有我想避免的缺点.我可以使该类的Common版本具体化,但这首先会破坏具有此层次结构的目的.我不希望通用版本被实例化并可能持久化.仅制造商应用程序应该这样做.我可以在Product应用程序中创建一个具体的类,但是这需要在数据库中添加一个在休眠之外毫无意义的DTYPE.最后也是最糟糕的选择是使产品和制造商具有直接依赖性.我什至没有考虑,除非其他所有可能性都用尽了.

There are three options I can see right now, but they all come with drawbacks I would like to avoid. I could make the Common version of the class concrete, but that would defeat the purpose of having this hierarchy in the first place. I don't want the common version to get instantiated and potentially persisted. Only the Manufacturer application should be doing that. I could create a concrete class in the Product application, but that would require adding a DTYPE to the database that is meaningless outside of hibernate. The final, and worst, option would be to make Product and Manufacturer have a direct dependency. I'm not even considering that unless every other possibility is exhausted.

我觉得必须有一些干净的方法来做我需要的事情.任何帮助将不胜感激.

I feel like there must be some clean way of doing what I need. Any help would be greatly appreciated.

推荐答案

一个

A mapped superclass isn't an entity. It's only a class that shares its mapping definition with its subclasses. You, therefore, can't select it with Hibernate or any other JPA implementation.

如果要在查询中选择超类或定义多态关联,则应查看

If you want to select the superclass in a query or define polymorphic associations, you should look at the table per class strategy. It maps each concrete entity class to its own database table. You can set that strategy by annotating your superclass with @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS), e.g.:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Manufacturer { ... }


@Entity
public class Product extends Manufacturer { ...}

在下一步中,您需要确定您的超类是否应该是抽象的.使用每个类的表策略,可以使您的超类抽象化.这样,您将无法实例化和保留该类的任何对象.但是您可以在查询和关联映射中使用它们.然后,Hibernate总是返回特定的子类.

In the next step, you need to decide if your superclass shall be abstract or not. Using the table per class strategy, you can make your superclass abstract. You will then not be able to instantiate and persist any objects of that class. But you can use them in your queries and association mappings. Hibernate then always returns the specific subclass.

您写道,您希望使超类抽象化,而在您的一个应用程序中没有任何具体的子类.这听起来像是一个有问题的设计决策,因为您将无法在该应用程序中使用超类.Hibernate不会知道任何子类,因此您将无法选择或持久化它们.

You wrote that you would prefer to make the superclass abstract without having any concrete subclasses in one of your applications. That sounds like a questionable design decision because you wouldn't be able to use the superclass in that application. Hibernate wouldn't know any of the subclasses, and you wouldn't be able to select or persist them.

如果您想了解有关JPA映射继承层次结构的不同选项的更多信息,建议您阅读有关它的深入指南:

If you want to learn more about JPA's different options to map inheritance hierarchies, I recommend reading my in-depth guide about it: Inheritance Strategies with JPA and Hibernate – The Complete Guide

这篇关于使用Hibernate EntityManager获取映射的超类的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆