Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Multi-column, one-to-one, JPA 2.0 @EmbeddedId using @MapsId fails with read-only on @JoinColum
Multi-column, one-to-one, JPA 2.0 @EmbeddedId using @MapsId fails with read-only on @JoinColum [message #670572] Sun, 15 May 2011 02:22 Go to next message
Karsten Wutzke is currently offline Karsten Wutzke
Messages: 112
Registered: July 2009
Senior Member
I have already posted a rather long question over at SO, so I'll just post the link to that question here (tired of another formatting run sorry):

http://stackoverflow.com/questions/6006083/eclipselink-multi -column-one-to-one-jpa-2-0-embeddedid-using-mapsid-fails-wi

Can anyone please comment on this (here)?

Thanks
Karsten

[Updated on: Sun, 15 May 2011 02:24]

Report message to a moderator

Re: Multi-column, one-to-one, JPA 2.0 @EmbeddedId using @MapsId fails with read-only on @JoinColum [message #671017 is a reply to message #670572] Mon, 16 May 2011 14:47 Go to previous messageGo to next message
Chris Delahunt is currently offline Chris Delahunt
Messages: 1035
Registered: July 2009
Senior Member
I've replied there, but will post the same here:

EclipseLink interprets mapsId to mean the relationship controls the contact_id and ordinal_nbr columns defined in your Foos table. Because of this, when you mark the relationship fields as read-only, it means there are no writable mappings for these fields - mapsId tells the provider that the values need to be used from the relationship, yet the relationship is read only.

Is there any reason why you are using mapsId instead of just marking your relationship as the ID and then using a pk class?

Best Regards,
Chris
Re: Multi-column, one-to-one, JPA 2.0 @EmbeddedId using @MapsId fails with read-only on @JoinColum [message #671130 is a reply to message #671017] Mon, 16 May 2011 20:18 Go to previous messageGo to next message
Karsten Wutzke is currently offline Karsten Wutzke
Messages: 112
Registered: July 2009
Senior Member
Yes there is a reason. I have written a code generator and I have to find out why the posted mapping using JPA 2.0 @EmbeddedId + @MapsId syntax doesn't work in EclipseLink. So I'm not looking for an alternative/working solution here - I do have several Wink - but rather why this isn't working.

Now that I have re-analyzed my code it becomes clear that in JPA 2.0 and because there is a nested ID class it kind of replaces the JPA 1.0 style PK column fields there (which are annotated with @Column), so there's no other place where to assume the writable attributes: the @JoinColumn.

Further thought:

I hope you actually only mean "@MapsId assumes relationships to be writable only for multi-column nested ID classes" because only they replace the @Column annotation in the ID class. For single-column relationships the @Column would still be specifiable and would mean you technically can put read-only on either @JoinColumn or @Column.

I'd really like to know if I understood this correctly. I need some reassurence whether your policy actually only applies to nested multi-column ID classes (at least that's only what would make sense to me).

Thanks!
Karsten
Re: Multi-column, one-to-one, JPA 2.0 @EmbeddedId using @MapsId fails with read-only on @JoinColum [message #671313 is a reply to message #671130] Tue, 17 May 2011 13:16 Go to previous messageGo to next message
Chris Delahunt is currently offline Chris Delahunt
Messages: 1035
Registered: July 2009
Senior Member
Hello Karsten,

I'm not sure I understood your distinction on multi-column nested ID classes. MapsId means the relationship maps the targeted ID column; so the relationship controls the field/targeted mapping. So mapping in your embeddable is then set to read-only - since its value and the field are controlled/set through the relationship. If you mark the join column(s) as read-only, you then will not have a writable mapping for the field.

The above is true regardless of the type of pk used in the relationship target.

Put it another way, if you have both set to be writable, and put in different values, what would you expect to consistently happen? I hope you wouldn't expect the relationship value to change, so it means that the relationship value must always trump the value in the embeddable - so the embeddable mapping is essentially read-only.

Best Regards,
Chris
Re: Multi-column, one-to-one, JPA 2.0 @EmbeddedId using @MapsId fails with read-only on @JoinColum [message #671919 is a reply to message #671313] Thu, 19 May 2011 11:10 Go to previous message
Karsten Wutzke is currently offline Karsten Wutzke
Messages: 112
Registered: July 2009
Senior Member
Please have a look at the following example:

http://www.kawoolutions.com/media/groups-participations-rosters.png

Mappings:

Roster.java: (single-column auto-ID PK)
@Entity
@Table(name = "Rosters")
@Name(value = "roster")
public class Roster implements Serializable
{
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "id")
	private Integer id;

	...
}

Group.java: (multi-column PK)
@Entity
@Table(name = "Groups")
@Name(value = "group")
public class Group implements Serializable
{
	@EmbeddedId
	private GroupId embeddedId;

	...
}

GroupId.java: (Group ID class)
@Embeddable
public class GroupId implements Serializable
{
	@Column(name = "round_id")
	private Integer roundId;

	@Column(name = "ordinal_nbr")
	private Integer ordinalNbr = 1;

	...
}


--------------------------------------------------------------------------------------------------------------------------------------------------------


Participation.java: (multi-column PK join table!)
@Entity
@Table(name = "Participations")
@Name(value = "participation")
public class Participation implements Serializable
{
	@EmbeddedId
	private ParticipationId embeddedId;

	@Column(name = "was_withdrawn")
	private Boolean wasWithdrawn;

	@ManyToOne
	@JoinColumn(name = "roster_id", referencedColumnName = "id")
	private Roster roster;

	@ManyToOne
	@JoinColumns(value = {@JoinColumn(name = "round_id", referencedColumnName = "round_id"), @JoinColumn(name = "group_ordinal_nbr", referencedColumnName = "ordinal_nbr")})
	private Group group;

	...
}

ParticipationId.java: (Participation ID class)
@Embeddable
public class ParticipationId implements Serializable
{
	// Roster reference: single-column
	@Column(name = "roster_id", insertable = false, updatable = false)
	private Integer rosterId;

	// Group reference: multi-column
	@Column(name = "round_id", insertable = false, updatable = false)
	private Integer roundId;

	@Column(name = "group_ordinal_nbr", insertable = false, updatable = false)
	private Integer groupOrdinalNbr;

	...
}


When you look at the mappings in Participation and ParticipationId you can choose to either include the read-only (insertable = false, updatable = false) in the @Column or the @JoinColumn annotations. This is what I mean by option. You have to make a decision here.

However, for JPA 2.0 @EmbeddedId derived identities the situation is different, because JPA 2.0 allows nesting of ID classes:

@Entity
@Table(name = "Participations")
@Name(value = "participation")
public class Participation implements Serializable
{
	@EmbeddedId
	private ParticipationId embeddedId;

	@Column(name = "was_withdrawn")
	private Boolean wasWithdrawn;

	@MapsId(value = "rosterId")
	@ManyToOne
	@JoinColumn(name = "roster_id", referencedColumnName = "id")
	private Roster roster;

	@MapsId(value = "groupId")
	@ManyToOne
	@JoinColumns(value = {@JoinColumn(name = "round_id", referencedColumnName = "round_id"), @JoinColumn(name = "group_ordinal_nbr", referencedColumnName = "ordinal_nbr")})
	private Group group;

	...
}


@Embeddable
public class ParticipationId implements Serializable
{
	// Roster reference: single-column
	@Column(name = "roster_id", insertable = false, updatable = false)
	private Integer rosterId;

	// Group reference: multi-column, BUT NO @JoinColumn choice!
	@Embedded
	private GroupId groupId;

	...
}


I could still decide whether to put the read-only on the single-column relationship (@JoinColumn) or the @EmbeddedId PK field (@Column), but it's technically "impossible" for multi-column JPA 2.0 @EmbeddedId derived identities because of the nested ID class. This choice is essentially "replaced" by the @MapsId JPA or JPA provider policy.

That's all that there is to it. So, the @MapsId actually only implements the policy you mentioned for JPA 2.0 derived identities' multi-column relationships???

Karsten
Previous Topic:Problem with QueryHints.BATCH/FetchType.EAGER
Next Topic:eclipselink does two inserts and one update when using cyclic references
Goto Forum:
  


Current Time: Thu Oct 30 23:54:49 GMT 2014

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

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