Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » (no subject)
(no subject) [message #726017] Fri, 16 September 2011 08:15 Go to next message
J F is currently offline J F
Messages: 242
Registered: July 2009
Senior Member
I have an Entity (Child1) which is identified by a Compound Primary Key.

I have two (to keep it simple) unidirectional relationships from another Entity (OtherThing) to that Entity (Child1).
If I do not annotate the relationship with a JoinCoumns then I get an error from Eclipselink;


Exception [EclipseLink-48] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Multiple writable mappings exist for the field [OTHERTHING.MYKEY]. Only one may be defined as writable, all others must be specified read-only.
Mapping: org.eclipse.persistence.mappings.ManyToOneMapping[refTwo]
Descriptor: RelationalDescriptor(uk.co.his.test.xref1.OtherThing --> [DatabaseTable(OTHERTHING)])

Exception [EclipseLink-48] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Multiple writable mappings exist for the field [OTHERTHING.ROOT_ID]. Only one may be defined as writable, all others must be specified read-only.
Mapping: org.eclipse.persistence.mappings.ManyToOneMapping[refTwo]
Descriptor: RelationalDescriptor(uk.co.his.test.xref1.OtherThing --> [DatabaseTable(OTHERTHING)])


I do not have a pre existing set of tables to map to in this case.

Is there some way to get Eclipselink to generate the join columns in the source Entity (OtherThing)? After all, all I am doing is generating unique column names by prefixing them with the field name?

IFF Child1 had not had a CompoundKey I would not have had to annotate the relationships. As it is I am compelled to know what column names to use in the referencedColumnName attribute of each JoinColumn, which means I must be able to anticipate how Eclipselink generates them or annotate all potential target columns with column names.



=== A Standard Container type object which contains Child objects, normally this would have been a Map type association with a @MapKey annotation
=== bit it is too large to implement that way

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.Id;

@Entity
public class Container1 {

@Id
public String id = "1";

public static final Container1 getInstance(EntityManager em) {
Container1 c = em.find(Container1.class, "1");
if (c == null) {
c = new Container1();
em.persist(c);
}
return c;
}

public Child1 createNewChild1(EntityManager em, String key) {
Child1 child1 = new Child1(this, key);
child1.setData(getTimestamp());
em.persist(child1);
return child1;
}

public Child1 getChild1(EntityManager em, String key) {
return em.find(Child1.class, new Child1.Child1Id(key, this));
}

private String getTimestamp()
{
DateFormat df = new SimpleDateFormat("hh:mm:ss.SSS", Locale.UK);
df.setTimeZone(TimeZone.getTimeZone("GB"));
return df.format(new Date());
}
}

=== A Child entity of the Container which is uniquely identified within a given Container1 instance by myKey

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

@Entity
@IdClass(Child1.Child1Id.class)
public class Child1 {

public static class Child1Id {
private String root;
private String myKey;
public Child1Id() {}
public Child1Id(String key, Container1 container) {
this.myKey = key;
this.root = container.id;
}
public String getRoot() {
return root;
}
public String getMyKey() {
return myKey;
}

}
@Id
@ManyToOne
private Container1 root;

@Basic
@Id
private String myKey;

@Basic
private String data;

public Child1() {}

public Child1(Container1 root, String key) {
this.root = root;
this.myKey = key;
}

public String getData() {
return data;
}

public void setData(String data) {
this.data = data;
}

public Container1 getRoot() {
return root;
}

public String getKey() {
return myKey;
}

}

======================== An Entity which has 2 unidirectional relationships to Child1

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.ManyToOne;

@Entity
public class OtherThing {


@SuppressWarnings("unused") //JPA
@Id
private String thingId;

@ManyToOne
Child1 refOne;

@ManyToOne
@JoinColumns({
@JoinColumn(name="refTwo_id", referencedColumnName="ROOT_ID"),
@JoinColumn(name="refTwo_mykey", referencedColumnName="MYKEY")
})
Child1 refTwo;
}
Re: (no subject) [message #730524 is a reply to message #726017] Wed, 28 September 2011 10:49 Go to previous messageGo to next message
Guy Pelletier is currently offline Guy Pelletier
Messages: 19
Registered: July 2009
Junior Member
Looks like you are hitting the following bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=357407

Please vote for it.

In the mean time, the work around is as you have already done, i.e. to specify the join columns (otherwise they default to the same for both mappings)

Re: (no subject) [message #730529 is a reply to message #726017] Wed, 28 September 2011 10:49 Go to previous message
Guy Pelletier is currently offline Guy Pelletier
Messages: 19
Registered: July 2009
Junior Member
Looks like you are hitting the following bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=357407

Please vote for it.

In the mean time, the work around is as you have already done, i.e. to specify the join columns (otherwise they default to the same for both mappings)
Previous Topic:JPA Relationship + Multi-Tenancy
Next Topic:How can I get the child entitites on a XML marshalling using @XmlID and @XmlIDREF annotations. I onl
Goto Forum:
  


Current Time: Thu Apr 24 01:35:20 EDT 2014

Powered by FUDForum. Page generated in 0.32696 seconds