[jboss-user] [EJB 3.0] - Cannot join @OneToOne on non-PK fields?

tsar_bomba do-not-reply at jboss.com
Wed Nov 8 12:44:06 EST 2006


I have a very simple case where I'm joining two entities w/ @OneToOne on fields of which neither side are primary keys...I have no choice, it's a legacy database and it's ugly.

I'm porting this code from Glassfish to JBoss...the kicker is; it works on Glassfish but breaks when running it on JBoss, obviously the question is how Hibernate handles this relationship vs. Toplink in Glassfish.

Here are the entities w/ the relationships:


  | @Entity
  | @Table(name="chg")
  | public class ChangeOrder implements Serializable
  | {
  | 	@Id
  | 	@Column(name="id", nullable=false)
  | 	private Integer id;
  | 
  | 	@Column(name="status", insertable=false, updatable=false)
  | 	private String status;
  | 
  |         @OneToOne(fetch=FetchType.LAZY)
  |         @JoinColumn(name="status", referencedColumnName="code")
  |         private ChangeOrderStatus changeOrderStatus;
  | ................................
  | }
  | 
  | @Entity
  | @Table(name="chgstat")
  | public class ChangeOrderStatus implements Serializable
  | {
  | 	@Id
  | 	@Column(name="id", nullable=false)
  | 	private int id;
  | 
  | 	@Column(name="code", nullable=false, insertable=false, updatable=false)
  | 	private String code;
  | 
  | 	@OneToOne(mappedBy="changeOrderStatus", fetch=FetchType.LAZY)
  | 	private ChangeOrder changeOrder;
  | .........................
  | }
  | 

Here is how I'm querying these entities:


  |   public List<ChangeOrder> getChangeOrders(Integer orgId)
  |   {
  |     String query = "select cho from ChangeOrder cho " +
  |         "left join fetch cho.changeOrderStatus " + 
  |         "where cho.organizationId = :orgId " +
  |         "and cho.activeFlag = 1 " +
  |         "order by cho.priority desc";
  |     
  |     Query q = this.em.createQuery(query);
  |     q.setParameter("orgId", orgId);
  |     
  |     return q.getResultList();
  |   }
  | 

Here is the SQL that is generated...which mysteriously, runs just fine against the database when executed manually!


  | Hibernate: 
  |     /* select
  |         cho 
  |     from
  |         ChangeOrder cho 
  |     left join
  |         fetch cho.changeOrderStatus 
  |     where
  |         cho.organizationId = :orgId 
  |         and cho.activeFlag = 1 
  |     order by
  |         cho.priority desc */ 
  |         select
  |           ...lots of fields here...
  |         from
  |             chg changeorde0_ 
  |         left outer join
  |             chgstat changeorde1_ 
  |                 on changeorde0_.status=changeorde1_.code 'this is correct!!
  |         where
  |             changeorde0_.organization=? 'I pass in this parameter...
  |             and changeorde0_.active_flag=1 
  |         order by
  |             changeorde0_.priority desc
  | Hibernate: 
  |     /* load com.myapp.model.ChangeOrder */ 
  |     select
  |       ...lots of fields here...
  |     from
  |         chg changeorde0_ 
  |     where
  |         changeorde0_.status=?
  | 

...also notice that even though I've specified LAZY loading on the owning side of the relationship...it is getting loaded eagerly...I would not have expected to see that second query being generated.

Here is the exception I get:


  | javax.ejb.EJBException
  | .......................
  | Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Syntax error converting the varchar value 'CL' to a column of data type int.
  |         at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(Unknown Source)
  |         at com.microsoft.sqlserver.jdbc.IOBuffer.processPackets(Unknown Source)
  |         at com.microsoft.sqlserver.jdbc.SQLServerStatement.buildNextRowset(Unknown Source)
  |         at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(Unknown Source)
  |         at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.getPrepExecResponse(Unknown Source)
  |         at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(Unknown Source)
  |         at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PreparedStatementExecutionRequest.executeStatement(Unknown Source)
  |         at com.microsoft.sqlserver.jdbc.CancelableRequest.execute(Unknown Source)
  |         at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeRequest(Unknown Source)
  |         at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeQuery(Unknown Source)
  |         at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:186)
  |         at org.hibernate.loader.Loader.getResultSet(Loader.java:1668)
  |         at org.hibernate.loader.Loader.doQuery(Loader.java:662)
  |         at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
  |         at org.hibernate.loader.Loader.loadEntity(Loader.java:1784)
  |         ... 90 more
  | 
  | 

'CL' is a status and would be found in ChangeOrder.status, so I'm unsure where this issue is happening.

I'm pretty sure something is going wrong w/ the second query...which I hoped to eliminate by setting the fetch type to 'lazy'.  I can't find the persistence.xml property to show the value being bound to the query so I'll just have to guess that it's trying to use an incorrect type, maybe the primary key from the other class?

I even tried flipping the relationship around so that ChangeOrder was the owning side, just to see what would happen, and predictably it generates incorrect SQL and throws an exception:


  | ...................
  |         from
  |             chg changeorde0_ 
  |         left outer join
  |             chgstat changeorde1_ 
  |                 on changeorde0_.id=changeorde1_.code 'wrong fields joined!
  |         where
  |             changeorde0_.organization=? 
  |             and changeorde0_.active_flag=1 
  |         order by
  |             changeorde0_.priority desc
  | 

Am I doing something wrong?  Like I said, this ran fine on Glassfish w/ Toplink but we'd like to move this app to a JBoss server in-house...we need this type of relationship to work.

I'd even be happy if it were uni-directional (though I can't change the tables)...I don't need the ChangeOrderStatus entity to have a reference to the ChangeOrder - that will never be used.

All help & suggestions are much appreciated, thanks.


View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3984256#3984256

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3984256



More information about the jboss-user mailing list