【问题标题】:eclipselink joined table inheritance causing errorseclipselink加入表继承导致错误
【发布时间】:2014-11-14 06:12:56
【问题描述】:

发行背景: 数据模型是实体钻孔,它可以有专门的子类型,如 GeotechicalBore、WaterBore、GeothermalBore 等。 我开始的实现是:

@Entity(name="BoreHole")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="BH_TYPE_ID",
discriminatorType=DiscriminatorType.INTEGER)
@DiscriminatorValue("5")
@Table(name="SC.BORE_HOLE")
public class BoreHole implements Serializable {
etc

subclasses are like:
@Entity(name = "GeothermalBore")
@Table(name = "MINERAL.GEOTHERMAL_BORE")
@DiscriminatorValue("8")
@PrimaryKeyJoinColumn(name="BH_ID",referencedColumnName="BH_ID")
public class GeothermalBore extends BoreHole{

@Entity(name = "PetroleumBore")
@Table(name = "PETROLEUM.PETROLEUM_BORE")
@DiscriminatorValue("1")
@PrimaryKeyJoinColumn(name="BH_ID",referencedColumnName="BH_ID")
public class PetroleumBore extends BoreHole{

所有重要的访问都是通过以下代码:

        EntityManagerFactory emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
        EntityManager em = emf.createEntityManager();
        TypedQuery<BoreHole> q = em.createQuery("SELECT x FROM BoreHole x where x.name = '" + name + "'", BoreHole.class);
        List<BoreHole> bhList = q.getResultList();

大多数情况下它都有效,但并非适用于所有课程。例如,上面的 PetroleumBore 工作,但 GeothermalBore 没有。我得到了错误:

javax.persistence.PersistenceException: Exception [EclipseLink-43] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Missing class for indicator field value [8] of type [class java.lang.Integer].
Descriptor: RelationalDescriptor(nz.cri.gns.jpaDatabase.entities.BoreHole.BoreHole --> [DatabaseTable(SC.BORE_HOLE)])

肯定有一个判别器值为 8 的类,它在persistance.xml 中。

大约在这一点上,事情迅速走下坡路。为了尝试跟踪有效的子类和无效的子类之间的差异,我将子类放入基础钻孔的同一个包中。无论如何,这似乎是更好的做法。当我这样做时,我得到了这种行为:

    TypedQuery<BoreHole> q = em.createQuery("SELECT x FROM BoreHole x where x.name = '" + name + "'", BoreHole.class);

生成类似的 SQL

SELECT BH_ID, BH_TYPE_ID, etc FROM SC.BORE_HOLE WHERE((BH_NAME = ?) AND (BH_TYPE_ID =))"))

但它总是绑定基础钻孔类的鉴别器值。 (值 5)。即它正在选择 BoreHole 的特定实例和 不是任何子类。我是 JPA 的菜鸟,但这看起来像所有 我见过的例子。

后退一步。下一步是如何让 BoreHole 成为一个抽象类并将所有钻孔作为子类派生? 即:

@Entity(name="BoreHole")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="BH_TYPE_ID", discriminatorType=DiscriminatorType.INTEGER)
@Table(name="SC.BORE_HOLE")
public abstract class BoreHole implements Serializable {

像以前一样的子实体。 彻底失败。我现在收到这些错误:

Exception [EclipseLink-108] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Cannot find value in class indicator mapping in parent descriptor [null].
Descriptor: RelationalDescriptor(nz.cri.gns.jpaDatabase.entities.BoreHole.BoreHole --> [DatabaseTable(SC.BORE_HOLE)])

Exception [EclipseLink-41] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: A non-read-only mapping must be defined for the sequence number field.
Descriptor: RelationalDescriptor(nz.cri.gns.jpaDatabase.entities.BoreHole.BoreHole --> [DatabaseTable(SC.BORE_HOLE)]) 

我要倒退而不是前进,互联网上的类似查询似乎没有得到解答。

【问题讨论】:

  • 将日志记录设置为最好,并在部署持久性单元时查看日志(EclipseLink 延迟加载,因此可能在第一次访问 EntityManager 时发生)。这应该表明它尝试加载持久性单元中的所有实体 - 检查它们是否都被找到并按照您的预期加载。
  • 谢谢克里斯。我确实将日志记录设置为最好,所以我会立即尝试。

标签: java jpa eclipselink


【解决方案1】:

非常感谢克里斯的提示。我确实查看了日志,但正在寻找错误。按照建议进行操作,我可以将问题跟踪到persistence.xml 中的大写拼写错误,我认为这一定很简单,但在错误的位置查找拼写错误。

3天无进展后,一切又好了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-07
    • 2017-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多