tags:

views:

794

answers:

2

I have a query that works in plain SQL but is not working on JPA and can't figure out why. As you can guess from the title I have a clue but I don't know how to "fix" it.

Here's the actual important code:

@Id 
@Basic(optional = false) 
@Column(name = "id", nullable = false) 
private Integer id; 

@Basic(optional = false) 
@Column(name = "read_permission", nullable = false) 
private boolean readPermission; 

@Basic(optional = false) 
@Column(name = "write_permission", nullable = false) 
private boolean writePermission; 

@Basic(optional = false) 
@Column(name = "execute_permission", nullable = false) 
private boolean executePermission; 

@Basic(optional = false) 
@Column(name = "admin_permission", nullable = false) 
private boolean adminPermission; 

@JoinColumn(name = "xinco_core_data_id", referencedColumnName = "id", nullable=true) 
@ManyToOne(fetch = FetchType.LAZY) 
private XincoCoreData xincoCoreDataId; 
@JoinColumn(name = "xinco_core_group_id", referencedColumnName = "id", nullable=true) 
@ManyToOne(fetch = FetchType.LAZY) 
private XincoCoreGroup xincoCoreGroupId; 

@JoinColumn(name = "xinco_core_node_id", referencedColumnName = "id", nullable=true) 
@ManyToOne(fetch = FetchType.LAZY) 
private XincoCoreNode xincoCoreNodeId; 

@JoinColumn(name = "xinco_core_user_id", referencedColumnName = "id", nullable=true) 
@ManyToOne(fetch = FetchType.LAZY) 
private XincoCoreUser xincoCoreUserId;

And here's the working sql:

select * from xinco_core_ace where xinco_core_user_id = 1 order by xinco_core_user_id, xinco_core_node_id, xinco_core_data_id;

And here's what I'm attempting to do:

SELECT xca FROM XincoCoreAce xca WHERE xca.xincoCoreUserId.id = 1 ORDER BY xca.xincoCoreUserId.id, xca.xincoCoreGroupId.id, xca.xincoCoreNodeId.id, xca.xincoCoreDataId.id

The issue, I think, is that the xca.xincoCoreUserId.id, xca.xincoCoreGroupId.id, xca.xincoCoreNodeId.id, xca.xincoCoreDataId.id can be nulls.

Any idea? Hopefully is easier to read :P

A: 

I'm no JPA expert here, but I'd try to get the actual SQL that is run on the database. Maybe the FetchType.LAZY has something to do with the problem?

kovica
If you are using Hibernate as your JPA provider you can have a look at http://www.javalobby.org/java/forums/t44119.htmlIt is a bit old, so I hope it still works.
kovica
I'm using EclipseLink but I'll take a look anyways.
javydreamercsw
This is the actual query done (using eclipselink logging):SELECT t1.id, t1.write_permission, t1.admin_permission, t1.execute_permission, t1.read_permission, t1.xinco_core_user_id, t1.xinco_core_data_id, t1.xinco_core_group_id, t1.xinco_core_node_id FROM xinco_core_data t4, xinco_core_node t3, xinco_core_group t2, xinco_core_ace t1, xinco_core_user t0 WHERE ((t3.id = ?) AND ((((t3.id = t1.xinco_core_node_id) AND (t0.id = t1.xinco_core_user_id)) AND (t2.id = t1.xinco_core_group_id)) AND (t4.id = t1.xinco_core_data_id))) ORDER BY t0.id ASC, t2.id ASC, t3.id ASC, t4.id ASC bind => [1]
javydreamercsw
I ran that query against the database and returned an empty result. I'll keep looking at the SQL to see what's wrong.
javydreamercsw
Well it looks kind of obvious that if some values are null they'll fail some of the where statements. If I remove all the where statements excpet t3.id=? it works. I'll try to remove the LAZY part and see what happens.
javydreamercsw
If I change the Fetch Type to eager I get the same result. I don't understand why it goes from a simple id check to a multiple field where statement.
javydreamercsw
If I removed the order by part I get the expected result but not in order. It really doesn't make sense to have a join there in the generated query.
javydreamercsw
A: 

This is the actual query done (using eclipselink logging):

SELECT t1.id, t1.write_permission, t1.admin_permission, t1.execute_permission, t1.read_permission, t1.xinco_core_user_id, t1.xinco_core_data_id, t1.xinco_core_group_id, t1.xinco_core_node_id FROM xinco_core_data t4, xinco_core_node t3, xinco_core_group t2, xinco_core_ace t1, xinco_core_user t0 WHERE ((t3.id = ?) AND ((((t3.id = t1.xinco_core_node_id) AND (t0.id = t1.xinco_core_user_id)) AND (t2.id = t1.xinco_core_group_id)) AND (t4.id = t1.xinco_core_data_id))) ORDER BY t0.id ASC, t2.id ASC, t3.id ASC, t4.id ASC bind => [1]

For some reason having the Order by adds a lot of table crosschecking in which having nulls make the result come out empty.

Removing the order by gets the required result (out of order of course).

See this Eclipselink bug

javydreamercsw