Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Madness with compound primary key(Continuous reluctance of EclipseLink to cooperate with examples found in the web)
Madness with compound primary key [message #855833] Wed, 25 April 2012 06:22 Go to next message
Bjoern Wuest is currently offline Bjoern Wuest
Messages: 1
Registered: April 2012
Junior Member
Hello,

here is what I ultimately try to do:

table_1
=======
int column_a is PK

table_2
=======
int column_a is PK as well as FK to table_1.column_a
int column_b is PK

table_3
=======
int column_a is PK as well as FK to table_1.column_a
int column_b is PK as well as FK to table_1.column_a
int column_c is PK


As I could not get it to work, I started with a very small example of compound primary key. Below is the class I have written for this.


import javax.persistence.Basic;
import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;

@Entity
public class DTest {
	@Embeddable
	public class PK {
		@Basic private long First;
		@Basic private long Second;
		
		public PK() {}
		
		public PK(long F, long S) {
			First = F;
			Second = S;
		}
		
		public boolean equals(Object O) { return false; }
		public int hashCode() { return 0; }
	}
	
	@EmbeddedId private PK m_PK;
	
	private long m_Third;
	
	public DTest() {}
	
	public DTest(long F, long S, long T) {
		m_PK = new PK(F, S);
		m_Third = T;
	}
}


However, when I compile and run the example, I get the following error message from EL:

Quote:
Exception [EclipseLink-30005] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.PersistenceUnitLoadingException
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: sun.misc.Launcher$AppClassLoader@1284903
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [test] failed.
Internal Exception: Exception [EclipseLink-7298] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The mapping [this$0] from the embedded ID class [class DTest$PK] is an invalid mapping for this class. An embeddable class that is used with an embedded ID specification (attribute [m_PK] from the source [class DTest]) can only contain basic mappings. Either remove the non basic mapping or change the embedded ID specification on the source to be embedded.



Thus, I took another attempt using @IdClass with the example below:


import javax.persistence.Basic;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Entity;

@Entity
@IdClass(DTest.PK.class)
public class DTest {
	public class PK {
		@Basic private long First;
		@Basic private long Second;
		
		public PK() {}
		
		public PK(long F, long S) {
			First = F;
			Second = S;
		}
		
		public boolean equals(Object O) { return false; }
		public int hashCode() { return 0; }
	}
	
	@Id private long First;
	@Id private long Second;
	
	private long m_Third;
	
	public DTest() {}
	
	public DTest(long F, long S, long T) {
		First = F;
		Second = S;
		m_Third = T;
	}
}


When compile and run this class, I get the following error message:

Quote:
Exception [EclipseLink-30005] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.PersistenceUnitLoadingException
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: sun.misc.Launcher$AppClassLoader@1284903
Internal Exception: javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [test] failed.
Internal Exception: Exception [EclipseLink-7150] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Invalid composite primary key specification. The names of the primary key fields or properties in the primary key class [DTest$PK] and those of the entity bean class [class DTest] must correspond and their types must be the same. Also, ensure that you have specified ID elements for the corresponding attributes in XML and/or an @Id on the corresponding fields or properties of the entity class.



I am a little bit puzzled what could be wrong. According to numerous tutorials on the Web, both above classes shall work. But maybe I made some mistake I do not see. Any advice is greatly appreciated.


Cheers
Bjoern
Re: Madness with compound primary key [message #857398 is a reply to message #855833] Thu, 26 April 2012 13:55 Go to previous messageGo to next message
James Sutherland is currently offline James Sutherland
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

It looks like your inner class has a special variable generated by the compiler "this$0", which I assume is a reference back to the owning class. When EclipseLink encounters this variable it does not know how to map it.

Try defining the class as "static" or in its own file. I do not think you can map non-static inner classes, as they are not independent objects.


James : Wiki : Book : Blog : Twitter
Re: Madness with compound primary key [message #857403 is a reply to message #855833] Thu, 26 April 2012 14:00 Go to previous message
Chris Delahunt is currently offline Chris Delahunt
Messages: 1021
Registered: July 2009
Senior Member
I've never seen an inner class used as a primary key class - have you tried seperating it out into its own class?

That, and I do not see how this will work. The class shown seems to be for table 2 and will need to reference the first table which it does not do.

If using JPA 2.0, Something like:
@Entity
@IdClass(Table2_PK.class)
public class Table2 {
  @ID
  @OneToOneMapping
  @JoinColumn(name="COLUMN_A")
  private Table1 t1Reference;
  
  @ID
  @Column(name="COLUMN_B")
  private long second;
...


public class Table2_PK.class {
  private long t1Reference; //type must match the pk defined in Table1 
  private long second;
}  
Previous Topic:Setting batch size in EclipseLink 1.1.4
Next Topic:Where is the javax.persistence in EclipseLink?
Goto Forum:
  


Current Time: Fri Sep 19 02:03:21 GMT 2014

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

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