Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » GF 3.1 + EclipseLink 2.1.1 - Map/Hashmap not working properly with changetracking enabled
GF 3.1 + EclipseLink 2.1.1 - Map/Hashmap not working properly with changetracking enabled [message #628842] Fri, 24 September 2010 11:59 Go to next message
Jack  is currently offline Jack Friend
Messages: 11
Registered: September 2010
Junior Member
Hi,

we recently switched to static weaving as OneToOne lazy loading did not work in our application (see: http://www.eclipse.org/forums/index.php?t=msg&th=175837& amp;start=0)

We have set the following properties to our persistence.xml and now Eclipselink does not persist a Map/HashMap correctly:
<property name="eclipselink.target-database" value="PostgreSQL"/>
<property name="eclipselink.target-server" value="SunAS9"/>
<property name="eclipselink.weaving" value="static"/>
<property name="eclipselink.weaving.lazy" value="true"/>
<property name="eclipselink.weaving.fetchgroups" value="true"/>
<property name="eclipselink.weaving.internal" value="true"/>
<property name="eclipselink.weaving.eager" value="true"/>
<property name="eclipselink.weaving.changetracking" value="true"/>


In our application we have three classes: UserAccount, UserRole and DataAccessPrivileges. Each UserAccount can have several UserRoles and for each UserRole a UserAccount can have different DataAccessPriviliges.

Stripped down Version of relevant classes:

@Entity 
public class UserAccount implements Serializable {

    @Id
    private Long id;
    
    @OneToMany(fetch = FetchType.LAZY, 
    		   cascade = CascadeType.ALL,
    		   targetEntity = DataAccessPriviliges.class,
    		   orphanRemoval = true)
    @JoinColumn(name = "useraccount_id")
    @MapKeyJoinColumn(name = "userrole_id")
    private Map<UserRole, DataAccessPriviliges> dataAccessPrivileges;

}



@Entity
@Table(name = "c_useraccounts_userroles")
public class DataAccessPriviliges implements Serializable {
	
        @Id
        private Long id;

	@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, targetEntity = LooselyReference.class)
	@JoinTable(name = "c_useraccounts_userroles_dap",
			   joinColumns = @JoinColumn(name = "useraccounts_userroles_id"),
			   inverseJoinColumns = @JoinColumn(name = "looselyreference_id"))
	private List<LooselyReference> accessibleObjects;

}


DataAccessPriviliges does not have a back-reference to its corresponding UserRole (the key of the map). Our database table that stores our map entrys looks like this:

CREATE TABLE c_useraccounts_userroles
(
  id serial NOT NULL,
  useraccount_id integer,
  userrole_id integer
)


Now when we create for example a new assignment between an existing UserRole with id 4 to an existing UserAccount with id 286 the following querys will be done by EclipseLink:

eclipselink.weaving.changetracking = false:
select nextval(c_useraccounts_userroles_id_seq)
INSERT IGNORE INTO c_useraccounts_userroles (id, lav) VALUES (?, ?)
	bind => [20, 14]
UPDATE c_useraccounts_userroles SET userrole_id = ?, useraccount_id = ? WHERE (id = ?)
	bind => [4, 286, 20]


eclipselink.weaving.changetracking = true:
select nextval(c_useraccounts_userroles_id_seq)
INSERT IGNORE INTO c_useraccounts_userroles (id, lav) VALUES (?, ?)
	bind => [21, 14]
UPDATE c_useraccounts_userroles SET userrole_id = ?, useraccount_id = ? WHERE (id = ?)
	bind => [4, 286, null]


As you can see, when changetracking is turned on, then EclipseLink somehow forgets the id = 21 used by the INSERT when EclipseLink wants to UPDATE the table row with the actual assignment between UserRole and UserAccount. So we now have an empty row in our table. When changetracking is set to false, everything works like expected (although its a bit strange that EclipseLink does an insert followed by an update).

Is there anything wrong in our map definition? I don't think so but perhaps I am missing something. For me it looks like a weaving bug.
Re: GF 3.1 + EclipseLink 2.1.1 - Map/Hashmap not working properly with changetracking enabled [message #629245 is a reply to message #628842] Mon, 27 September 2010 15:22 Go to previous messageGo to next message
James Sutherland is currently offline James SutherlandFriend
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

Very odd that change tracking is affecting an insert, as it only affects how updates are done.

Seems to be a bug related to the @MapKeyJoinColumn, if you remove the map key, does the issue go away? Ensure you have the latest release, if the issue still occurs you will need to log a bug for this (don't forget to vote for it).

Putting the reference to UserRole in the DataAccessPriviliges instead of using the MapKeyJoinColumn would probably be better. The update is required because the DataAccessPriviliges has no knowledge of the userrole_id column as it is maintained by the mapping.


James : Wiki : Book : Blog : Twitter
Re: GF 3.1 + EclipseLink 2.1.1 - Map/Hashmap not working properly with changetracking enabled [message #629352 is a reply to message #629245] Mon, 27 September 2010 22:11 Go to previous messageGo to next message
Jack  is currently offline Jack Friend
Messages: 11
Registered: September 2010
Junior Member
Thanks for your reply. As we haven't found a solution yet, we refactored our classes to use Lists instead of a Map hoping its only a map issue.

So basically we now have a List with UserRoleDataAccessPriviliges and the previous map key is now stored inside this class.

@Entity 
public class UserAccount implements Serializable {

    @Id
    private Long id;
    
    @OneToMany(fetch = FetchType.LAZY, 
    		   cascade = CascadeType.ALL,
    		   targetEntity = UserRoleDataAccessPrivileges.class)
    @JoinColumn(name = "useraccount_id")
    private List<UserRoleDataAccessPrivileges> userRoledataAccessPrivileges;

}



@Entity
@Table(name = "c_useraccounts_userroles")
public class UserRoleDataAccessPrivileges implements Serializable {
	
        @Id
        private Long id;

        @OneToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "userrole_id")
        private UserRole userRole;

	@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, targetEntity = LooselyReference.class)
	@JoinTable(name = "c_useraccounts_userroles_dap",
			   joinColumns = @JoinColumn(name = "useraccounts_userroles_id"),
			   inverseJoinColumns = @JoinColumn(name = "looselyreference_id"))
	private List<LooselyReference> accessibleObjects;

}



But even with Lists the issue remains the same. With changetracking = false everything works fine, but with changetracking = true EclipseLink does not update the foreign key inside the "c_useraccounts_userroles" table which points to UserAccout. So Eclipselink performs an

INSERT IGNORE INTO c_useraccounts_userroles (id, userrole_id, lav) VALUES (?, ?, ?)
	bind => [21, 4, 14]

UPDATE c_useraccounts_userroles SET useraccount_id = ? WHERE (id = ?)
	bind => [286, null]


With Lists the INSERT directly adds userrole_id to the join table during the INSERT (with Map in the first post, userrole_id would be set during the UPDATE) but the UPDATE on useraccount_id fails because of "where id = null". With changetracking = false the update will be done with "where id = 21".

So I would guess its not really a bug related to @MapKeyJoinColumn as we now have no Map anymore but the issue remains the same.
Re: GF 3.1 + EclipseLink 2.1.1 - Map/Hashmap not working properly with changetracking enabled [message #630049 is a reply to message #628842] Thu, 30 September 2010 14:02 Go to previous message
James Sutherland is currently offline James SutherlandFriend
Messages: 1939
Registered: July 2009
Location: Ottawa, Canada
Senior Member

It seems the issue is with the unidirection OneToMany (@JoinColumn(name = "useraccount_id") in your OneToMany). Please log a bug for this issue if it still occurs on the latest release.

If you add a ManyToOne back and use a mappedBy, or use a JoinTable the issue should go away.


James : Wiki : Book : Blog : Twitter
Previous Topic:Data Soruce in websphere is not working
Next Topic:Column "rowid" cannot be resolved
Goto Forum:
  


Current Time: Wed Nov 26 20:54:37 GMT 2014

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

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