openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From areider <open...@reider.net>
Subject assignment to persistent field FAIL; FIELD vs PROPERTY access
Date Sun, 10 Apr 2011 13:53:01 GMT
OPENJPA 1.2.3Snapshot, Rad 7.5.5

I am having a problem that an assignment to a persistent field in an entity
with accesstype FIELD is being ignored in a ~detached~ entity. Eg,

@OneToMany
private List articleList /* = new ArrayList() */ ;
public List getArticleList(){
	if (articleList != null) return articleList;
	articleList = new ArrayList();
	return articleList; // at this point, articleList == null!
}
The articleList field is not getting assigned. (Interestingly, if, in the
(Rad7(eclipse) debugger, breaking after the assignment, I swipe and evaluate
the assignment ~in an expression pane~, the field is assigned as expected).
(BTW, even if I specify the variable initializer the articleList is null
when the entity is fetched (and detached from the database)).

I'm guessing this is due to bytecode enhancement, the assignment has been
replaced with something else.

The full OTM and MTO mappings that I generate are shown below. The accessors
are designed for client use -  to ensure bidirectionality that works from
either side of the relationship , to lazy init the list, and in some cases
to do other bookkeeping or business logic. Presumably the accessors are not
used by OpenJPA because the access type is FIELD.

Changing the access type PROPERTY cures the assignment issue, but would be a
fundamental change with many ramifications. Eg. 
a) I don't want to expose those accessors to the persistence provider, they
are fragile for several reasons
a1) while the accessors as currently implemented appear to be tolerated by
OpenJPA (I only tested fetch, not persist), it would require a lot of
testing to prove it.
a2) some accessors may contain other logic. eg set a sequence number
according to the child's position in the parent list, or just business
related logic that assumes the entity is well-formed whenever the setter is
invoked.
a3) I dont want to have to change the accessType just to fix (allegedly)
incorrect behavior.
a4) The big reason: the accessors are subject to modification by application
developers and that could break them for OpenJPA.
b) The entities are rich domain objects with hundreds of
non-persistence-related methods, including bean-style getters that would (I
think?) have to be marked transient. I say I think, because I tried PROPERTY
access and JPA did not seem to generate column references in selects for my
non-persistent getXXX() methods.

I briefly thought about having a separate pair of accessors just for JPA, to
provide a clean seperation of provider accessors and client accessors, but
that still has the disadvantages of using PROPERTY described above.

My main question is, why is JPA no-oping that assignment and how can I
prevent it? The kicker is that in months of testing, this is the first time
I encountered the assignment problem, it has worked propertly in the past.

public class Magazine {
//	...
	@OneToMany(mappedBy="magazine")
	private List articleList /* = new ArrayList() */ ;
	public List getArticleList(){
		if (articleList != null) 
			return articleList; 
		articleList = new ArrayList();
		return articleList;
	}
	public void setArticleList(List ArticleList) {
		this.articleList = articleList;
	}
	public void addArticle(Article article){
		// if used by OpenJPA might need: if(article == null) return;
		List collection = getArticleList();
		if (collection.contains(article))	// avoid circularity, dupes
			return;
		collection.add(article);	
		article.setMagazine(this); // be bidirectional
	}
//	...
}
public class Article {
//	...
	@ManyToOne
	@JoinColumn(name="...")
	private Magazine magazine;
	public Magazine getMagazine(){
		return magazine;
	}
	public void setMagazine(Magazine newMagazine){
		if (this.magazine == newMagazine)  // avoid circularity
			return;
		if (magazine != null)
			magazine.getArticleList().remove(this); // disown current parent
		this.magazine = newMagazine;
		if (newMagazine == null)			// avoid bidectional if null parent
			return;
		newMagazine.addMagazine(this);	// be bidirectional
	}
//	...
}


--
View this message in context: http://openjpa.208410.n2.nabble.com/assignment-to-persistent-field-FAIL-FIELD-vs-PROPERTY-access-tp6258774p6258774.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Mime
View raw message