Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Compatibility of TABLE_PER_CLASS inheritance strategy with composite keys
Compatibility of TABLE_PER_CLASS inheritance strategy with composite keys [message #630514] Sun, 03 October 2010 16:44 Go to next message
dcarbonne  is currently offline dcarbonne
Messages: 14
Registered: October 2010
Junior Member
Hi,

Is there any (JPA) defined incompatibility between the TABLE_PER_CLASS inheritance strategy and the use of composite key?

With the following entities:
- BaseId: embeddable entity (to be used as embedded id)
- Base: base class, whose embedded id is BaseId and inheritance strategy is TABLE_PRE_CLASS
- Derived1: class derived from Base

EclipseLink (2.1.1) fails throwing an exception:
Exception [EclipseLink-74] (Eclipse Persistence Services - 2.1.1.v20100817-r8050): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: The primary key fields are not set for this descriptor.
Descriptor: RelationalDescriptor(jpa03.Derived1 --> [DatabaseTable(DERIVED1)])

However, changing the Base key from BaseId to any simple primary key (e.g. int), things work correctly.

So, is this a JPA limitation or an EclipseLink limitation / bug?
I have read that TABLE_PER_CLASS is optional, so it may well be an EclipseLink limitation, but I did not find any explicit statement about this.

Regards,
Damien Carbonne




Re: Compatibility of TABLE_PER_CLASS inheritance strategy with composite keys [message #630657 is a reply to message #630514] Mon, 04 October 2010 13:50 Go to previous messageGo to next message
Chris Delahunt is currently offline Chris Delahunt
Messages: 1035
Registered: July 2009
Senior Member
Can you post details on the EclipseLink version being used, the full stack trace from the error and the model being used? A similar setup exists in EclipseLink tests available at
https://fisheye2.atlassian.com/browse/eclipselink/trunk/jpa/ eclipselink.jpa.test/src/org/eclipse/persistence/testing/mod els/jpa/inheritance/Elimination.java?r=HEAD
https://fisheye2.atlassian.com/browse/eclipselink/trunk/jpa/ eclipselink.jpa.test/src/org/eclipse/persistence/testing/mod els/jpa/inheritance/Elimination.java?r=HEAD
https://fisheye2.atlassian.com/browse/eclipselink/trunk/jpa/ eclipselink.jpa.test/src/org/eclipse/persistence/testing/mod els/jpa/inheritance/DirectElimination.java?r=HEAD

Only difference is it is not using an EmbeddedId. Can you try directly mappiing the attributes on the base class instead?

Best Regards,
Chris
Re: Compatibility of TABLE_PER_CLASS inheritance strategy with composite keys [message #630768 is a reply to message #630657] Mon, 04 October 2010 21:16 Go to previous messageGo to next message
dcarbonne  is currently offline dcarbonne
Messages: 14
Registered: October 2010
Junior Member
Thanks for answer.

I use latest EclipseLink (2.1.1.v20100917), under Linux, with Eclipse Helios.
The same behaviour exists under Windows using the same versions of EclipseLink and Eclipse.

Code follows. I could also send an archive of this small project.
I'll try to see if I can use IdClass instead of EmbeddedId.

Best regards,
Damien


jpa03/BaseId.java
package jpa03;

import java.io.Serializable;
import java.lang.String;
import javax.persistence.*;

@Embeddable
public class BaseId implements Serializable {
   private static final long serialVersionUID = 1L;

   private String code;

   public BaseId() { super(); }

   public String getCode() { return this.code; }

   public void setCode(String code) { this.code = code; }

   @Override
   public boolean equals(Object other) {
      if (other == null)
         return false;
      if (!(other instanceof BaseId)) {
         return false;
      }
      BaseId o = (BaseId) other;
      return this.code.equals(o.code);
   }

   @Override
   public int hashCode() {
      return code.hashCode();
   }
}

jpa03/Base.java
package jpa03;

import java.io.Serializable;
import javax.persistence.*;
import jpa03.BaseId;
import static javax.persistence.InheritanceType.TABLE_PER_CLASS;

@Entity
@Inheritance(strategy = TABLE_PER_CLASS)
public class Base implements Serializable {
   private static final long serialVersionUID = 1L;

   @EmbeddedId
   private BaseId id;

   public Base() { super(); }

   public BaseId getId() { return this.id; }

   public void setId(BaseId id) { this.id = id; }
}

jpa03/Derived1.java
package jpa03;

import java.io.Serializable;
import javax.persistence.*;
import jpa03.Base;

@Entity
public class Derived1 extends Base implements Serializable {

   private static final long serialVersionUID = 1L;

   public Derived1() { super(); }
}


persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
  xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="jpa-03" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <class>jpa03.BaseId</class>
    <class>jpa03.Base</class>
    <class>jpa03.Derived1</class>
    <properties>
      <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
      <property name="javax.persistence.jdbc.url" value="jdbc:derby:/home/damien/workspace/db/jpa03;create=true" />
      <property name="javax.persistence.jdbc.user" value="" />
      <property name="javax.persistence.jdbc.password" value="" />
      <property name="eclipselink.logging.level" value="FINE" />
      <property name="eclipselink.ddl-generation.output-mode"
        value="both" />
    </properties>
  </persistence-unit>
</persistence>


Finally, when executing <JPA Tools/Generate Tables from Entities ...> (after having removed the Data Base) the stack trace is:
[EL Config]: The access type for the persistent class [class jpa03.Base] is set to [FIELD].
[EL Config]: The access type for the persistent class [class jpa03.Derived1] is set to [FIELD].
[EL Config]: The access type for the persistent class [class jpa03.BaseId] is set to [FIELD].
[EL Config]: The alias name for the entity class [class jpa03.Derived1] is being defaulted to: Derived1.
[EL Config]: The alias name for the entity class [class jpa03.Base] is being defaulted to: Base.
[EL Config]: The table name for entity [class jpa03.Base] is being defaulted to: BASE.
[EL Config]: The column name for element [field code] is being defaulted to: CODE.
[EL Config]: The table name for entity [class jpa03.Derived1] is being defaulted to: DERIVED1.
[EL Info]: EclipseLink, version: Eclipse Persistence Services - 2.1.1.v20100817-r8050
[EL Fine]: Detected Vendor platform: org.eclipse.persistence.platform.database.JavaDBPlatform
[EL Config]: Connection(12590745)--connecting(DatabaseLogin(
	platform=>JavaDBPlatform
	user name=> ""
	datasource URL=> "jdbc:derby:/home/damien/workspace/db/jpa03;create=true"
))
[EL Config]: Connection(8310136)--Connected: jdbc:derby:/home/damien/workspace/db/jpa03
	User: APP
	Database: Apache Derby  Version: 10.5.1.1 - (764942)
	Driver: Apache Derby Embedded JDBC Driver  Version: 10.5.1.1 - (764942)
[EL Config]: Connection(14910620)--connecting(DatabaseLogin(
	platform=>JavaDBPlatform
	user name=> ""
	datasource URL=> "jdbc:derby:/home/damien/workspace/db/jpa03;create=true"
))
[EL Config]: Connection(11731442)--Connected: jdbc:derby:/home/damien/workspace/db/jpa03
	User: APP
	Database: Apache Derby  Version: 10.5.1.1 - (764942)
	Driver: Apache Derby Embedded JDBC Driver  Version: 10.5.1.1 - (764942)
[EL Severe]: Local Exception Stack: 
Exception [EclipseLink-0] (Eclipse Persistence Services - 2.1.1.v20100817-r8050): org.eclipse.persistence.exceptions.IntegrityException
Descriptor Exceptions: 
---------------------------------------------------------

Exception [EclipseLink-74] (Eclipse Persistence Services - 2.1.1.v20100817-r8050): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: The primary key fields are not set for this descriptor.
Descriptor: RelationalDescriptor(jpa03.Derived1 --> [DatabaseTable(DERIVED1)])

Runtime Exceptions: 
---------------------------------------------------------

	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:471)
	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:406)
	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.postConnectDatasource(DatabaseSessionImpl.java:666)
	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:615)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:228)
	at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:380)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:157)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:214)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:202)
	at org.eclipse.jpt.eclipselink.core.ddlgen.Main.perform(Main.java:86)
	at org.eclipse.jpt.eclipselink.core.ddlgen.Main.execute(Main.java:77)
	at org.eclipse.jpt.eclipselink.core.ddlgen.Main.main(Main.java:64)

Descriptor Exceptions: 
---------------------------------------------------------


Local Exception Stack: 
Exception [EclipseLink-74] (Eclipse Persistence Services - 2.1.1.v20100817-r8050): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: The primary key fields are not set for this descriptor.
Descriptor: RelationalDescriptor(jpa03.Derived1 --> [DatabaseTable(DERIVED1)])
	at org.eclipse.persistence.exceptions.DescriptorException.primaryKeyFieldsNotSepcified(DescriptorException.java:1347)
	at org.eclipse.persistence.descriptors.ClassDescriptor.selfValidationBeforeInitialization(ClassDescriptor.java:3565)
	at org.eclipse.persistence.descriptors.ClassDescriptor.validateBeforeInitialization(ClassDescriptor.java:5280)
	at org.eclipse.persistence.descriptors.ClassDescriptor.preInitialize(ClassDescriptor.java:3346)
	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:429)
	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:406)
	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.postConnectDatasource(DatabaseSessionImpl.java:666)
	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:615)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:228)
	at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:380)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:157)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:214)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:202)
	at org.eclipse.jpt.eclipselink.core.ddlgen.Main.perform(Main.java:86)
	at org.eclipse.jpt.eclipselink.core.ddlgen.Main.execute(Main.java:77)
	at org.eclipse.jpt.eclipselink.core.ddlgen.Main.main(Main.java:64)

Runtime Exceptions: 
---------------------------------------------------------

[EL Severe]: Local Exception Stack: 
Exception [EclipseLink-0] (Eclipse Persistence Services - 2.1.1.v20100817-r8050): org.eclipse.persistence.exceptions.IntegrityException
Descriptor Exceptions: 
---------------------------------------------------------

Exception [EclipseLink-74] (Eclipse Persistence Services - 2.1.1.v20100817-r8050): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: The primary key fields are not set for this descriptor.
Descriptor: RelationalDescriptor(jpa03.Derived1 --> [DatabaseTable(DERIVED1)])

Runtime Exceptions: 
---------------------------------------------------------

	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:471)
	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:406)
	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.postConnectDatasource(DatabaseSessionImpl.java:666)
	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:615)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:228)
	at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:380)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:157)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:214)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:202)
	at org.eclipse.jpt.eclipselink.core.ddlgen.Main.perform(Main.java:86)
	at org.eclipse.jpt.eclipselink.core.ddlgen.Main.execute(Main.java:77)
	at org.eclipse.jpt.eclipselink.core.ddlgen.Main.main(Main.java:64)

Descriptor Exceptions: 
---------------------------------------------------------


Local Exception Stack: 
Exception [EclipseLink-74] (Eclipse Persistence Services - 2.1.1.v20100817-r8050): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: The primary key fields are not set for this descriptor.
Descriptor: RelationalDescriptor(jpa03.Derived1 --> [DatabaseTable(DERIVED1)])
	at org.eclipse.persistence.exceptions.DescriptorException.primaryKeyFieldsNotSepcified(DescriptorException.java:1347)
	at org.eclipse.persistence.descriptors.ClassDescriptor.selfValidationBeforeInitialization(ClassDescriptor.java:3565)
	at org.eclipse.persistence.descriptors.ClassDescriptor.validateBeforeInitialization(ClassDescriptor.java:5280)
	at org.eclipse.persistence.descriptors.ClassDescriptor.preInitialize(ClassDescriptor.java:3346)
	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:429)
	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:406)
	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.postConnectDatasource(DatabaseSessionImpl.java:666)
	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:615)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:228)
	at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:380)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:157)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:214)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:202)
	at org.eclipse.jpt.eclipselink.core.ddlgen.Main.perform(Main.java:86)
	at org.eclipse.jpt.eclipselink.core.ddlgen.Main.execute(Main.java:77)
	at org.eclipse.jpt.eclipselink.core.ddlgen.Main.main(Main.java:64)

Runtime Exceptions: 
---------------------------------------------------------

Exception in thread "main" javax.persistence.PersistenceException: Exception [EclipseLink-0] (Eclipse Persistence Services - 2.1.1.v20100817-r8050): org.eclipse.persistence.exceptions.IntegrityException
Descriptor Exceptions: 
---------------------------------------------------------

Exception [EclipseLink-74] (Eclipse Persistence Services - 2.1.1.v20100817-r8050): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: The primary key fields are not set for this descriptor.
Descriptor: RelationalDescriptor(jpa03.Derived1 --> [DatabaseTable(DERIVED1)])

Runtime Exceptions: 
---------------------------------------------------------

	at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:408)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:157)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:214)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:202)
	at org.eclipse.jpt.eclipselink.core.ddlgen.Main.perform(Main.java:86)
	at org.eclipse.jpt.eclipselink.core.ddlgen.Main.execute(Main.java:77)
	at org.eclipse.jpt.eclipselink.core.ddlgen.Main.main(Main.java:64)
Caused by: Exception [EclipseLink-0] (Eclipse Persistence Services - 2.1.1.v20100817-r8050): org.eclipse.persistence.exceptions.IntegrityException
Descriptor Exceptions: 
---------------------------------------------------------

Exception [EclipseLink-74] (Eclipse Persistence Services - 2.1.1.v20100817-r8050): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: The primary key fields are not set for this descriptor.
Descriptor: RelationalDescriptor(jpa03.Derived1 --> [DatabaseTable(DERIVED1)])

Runtime Exceptions: 
---------------------------------------------------------

	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:471)
	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:406)
	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.postConnectDatasource(DatabaseSessionImpl.java:666)
	at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:615)
	at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:228)
	at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:380)
	... 6 more

Re: Compatibility of TABLE_PER_CLASS inheritance strategy with composite keys [message #630770 is a reply to message #630657] Mon, 04 October 2010 21:27 Go to previous messageGo to next message
Chris Delahunt is currently offline Chris Delahunt
Messages: 1035
Registered: July 2009
Senior Member
Hello,

I've filed bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=326973 after reproducing your model using the classes I outlined previously. Please vote for the bug to have it fixed.

In the mean time, a workaround is to avoid using the embeddedId and instead map the fields directly in the object, using the embedded class as the pk class.

Best Regards,
Chris
Re: Compatibility of TABLE_PER_CLASS inheritance strategy with composite keys [message #631023 is a reply to message #630770] Tue, 05 October 2010 20:53 Go to previous message
dcarbonne  is currently offline dcarbonne
Messages: 14
Registered: October 2010
Junior Member
Thanks for doing this.
Damien
Previous Topic:MOXy/JAXB ClassCastException: attempting to cast bundleresource://.../JAXBContext.class to jar:file:
Next Topic:JPQL where condition problem
Goto Forum:
  


Current Time: Thu Oct 30 13:59:36 GMT 2014

Powered by FUDForum. Page generated in 0.02774 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software