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 |
Jack Mising name 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 |
|
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 |
Jack Mising name 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.
|
|
| |
Goto Forum:
Current Time: Tue Sep 24 09:45:13 GMT 2024
Powered by FUDForum. Page generated in 0.03387 seconds
|