[hibernate-issues] [Hibernate-JIRA] Commented: (ANN-548) Fails to map a FK pointing to a non PK whose columns are held by properies in component

Emmanuel Bernard (JIRA) noreply at atlassian.com
Sat Feb 10 02:26:40 EST 2007


    [ http://opensource.atlassian.com/projects/hibernate/browse/ANN-548?page=comments#action_26065 ] 

Emmanuel Bernard commented on ANN-548:
--------------------------------------

The unit test is located in org.hibernate.test.annotations.manytoone.ManyToOneOnNonPkTest, uncomment to make it fail

> Fails to map a FK pointing to a non PK whose columns are held by properies in component
> ---------------------------------------------------------------------------------------
>
>          Key: ANN-548
>          URL: http://opensource.atlassian.com/projects/hibernate/browse/ANN-548
>      Project: Hibernate Annotations
>         Type: Bug

>   Components: binder
>     Versions: 3.2.1, 3.2.2
>  Environment: JBoss 4.0.5.GA w/ Hibernate 3.2.2 and Annoations 3.2.2 (from SVN).  Also reproduced w/ JBoss 4.0.5.GA w/ stock annotations, hibernate, and entity manager, unmodified.  The attached test-case was run against MSSQL 2000 but is trivial to point at another database.  The issue was also reproduced on a OpenEdge Progress 10.1A database.
>     Reporter: Vincent Jenks
>     Priority: Minor
>  Attachments: CarBean.java, Carz.java, Lotz.java
>
>
> Joins break when using composite primary key classes
> JBoss 4.0.5.GA w/ Hibernate 3.2.2 and Annoations 3.2.2 (from SVN).  Also reproduced w/ JBoss 4.0.5.GA w/ stock annotations, hibernate, and entity manager, unmodified.  The attached test-case was run against MSSQL 2000 but is trivial to point at another database.  The issue was also reproduced on a OpenEdge Progress 10.1A database.
> In a case where there are composite keys on one (or each) side of a relationship, Hibernate cannot join the entities together if all of the primary key fields are not used in the relationship.
> A (very) simple example, two entities Carz and Lotz (pardon the names, it's simply cars and car lots):
> @Entity
> @Table(name="car")
> public class Carz implements Serializable
> {
>   @Id
>   private Integer id;
>   
>   @Column(name="make", nullable=false)
>   private String make;
>   @Column(name="model", nullable=false)
>   private String model;
>   @Column(name="manufactured", nullable=false)
>   @Temporal(TemporalType.TIMESTAMP)
>   private Date manufactured;
>   
>   @ManyToOne(fetch=FetchType.LAZY)
>   @JoinColumns //Hibernate docs state that @JoinColumns must be used since Lotz has composite PK, a single @JoinColumn does not deploy anyhow
>   ({
> 	  @JoinColumn(name="loc_code", referencedColumnName="loc_code", insertable=false, updatable=false)
>   })
>   private Lotz lot;
> ...........................
> }
> @Entity
> @Table(name="lot")
> public class Lotz implements Serializable
> {
> 	@EmbeddedId
> 	protected LotzPK lotPK;
> 	
>   @Column(name="name", nullable=false)
>   private String name;
>   @Column(name="location", nullable=false)
>   private String location;
>   @OneToMany(mappedBy="lot", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
>   private List<Carz> cars;
> ...........................
> }
> @Embeddable
> public class LotzPK implements Serializable
> {
>   @Column(name="id", nullable=false)
>   private Integer id;
>   
>   @Column(name="loc_code", nullable=false)
>   private String locCode;
> ...........................
> }
> In this case I need a one-to-many relationship on Carz.id = Lotz.locCode.  However, there doesn't appear to be a way to do this.  
> When this is deployed, this exception occurs:
> org.hibernate.AnnotationException: Column name id of hqb.model.Lotz not found in JoinColumns.referencedColumnName
> 	at org.hibernate.cfg.annotations.TableBinder.bindFk(TableBinder.java:306)
> 	at org.hibernate.cfg.FkSecondPass.doSecondPass(FkSecondPass.java:64)
> 	at org.hibernate.cfg.AnnotationConfiguration.processFkSecondPassInOrder(AnnotationConfiguration.java:433)
> 	at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:287)
> 	at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1115)
> 	at org.hibernate.ejb.Ejb3Configuration.buildMappings(Ejb3Configuration.java:1211)
> 	at org.hibernate.ejb.EventListenerConfigurator.configure(EventListenerConfigurator.java:154)
> 	at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:847)
> 	at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:385)
> 	at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:126)
> 	at org.jboss.ejb3.entity.PersistenceUnitDeployment.start(PersistenceUnitDeployment.java:264)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> 	at java.lang.reflect.Method.invoke(Method.java:597)
> 	at org.jboss.ejb3.ServiceDelegateWrapper.startService(ServiceDelegateWrapper.java:102)
> 	at org.jboss.system.ServiceMBeanSupport.jbossInternalStart(ServiceMBeanSupport.java:289)
> 	at org.jboss.system.ServiceMBeanSupport.jbossInternalLifecycle(ServiceMBeanSupport.java:245)
> 	at sun.reflect.GeneratedMethodAccessor263.invoke(Unknown Source)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> 	at java.lang.reflect.Method.invoke(Method.java:597)
> ...........................
> I can deploy the app if I map both fields in the Lotz PK class like so:
> @Entity
> @Table(name="car")
> public class Carz implements Serializable
> {
>   @Id
>   private Integer id;
> ...........................
>   
>   @ManyToOne(fetch=FetchType.LAZY)
>   @JoinColumns
>   ({
> 	  @JoinColumn(name="loc_code", referencedColumnName="loc_code", insertable=false, updatable=false),
> 	  @JoinColumn(name="", referencedColumnName="id", insertable=false, updatable=false) //INCORRECTLY DEFINED RELATIONSHIP!
>   })
>   private Lotz lot;
> ...........................
> }
> But obviously this is no good, it generates bad SQL at runtime:
>     /* select
>         c 
>     from
>         Carz c 
>     left join
>         fetch c.lot */ select
>             carz0_.id as id198_0_,
>             lotz1_.id as id199_1_,
>             lotz1_.loc_code as loc2_199_1_,
>             carz0_.make as make198_0_,
>             carz0_.model as model198_0_,
>             carz0_.manufactured as manufact4_198_0_,
>             carz0_.lot_id as lot5_198_0_,
>             carz0_.loc_code as loc6_198_0_, --no such column...
>             lotz1_.name as name199_1_,
>             lotz1_.location as location199_1_ 
>         from
>             car carz0_ 
>         left outer join
>             lot lotz1_ 
>                 on carz0_.lot_id=lotz1_.id --oops! Hibernate defaulted a relationship here...
>                 and carz0_.loc_code=lotz1_.loc_code
> In reality, this is the SQL I'm trying to achieve, by repairing the above query manually:
> select
>             carz0_.id as id198_0_,
>             lotz1_.id as id199_1_,
>             lotz1_.loc_code as loc2_199_1_,
>             carz0_.make as make198_0_,
>             carz0_.model as model198_0_,
>             carz0_.manufactured as manufact4_198_0_,
>             carz0_.loc_code as loc6_198_0_,
>             lotz1_.name as name199_1_,
>             lotz1_.location as location199_1_ 
>         from
>             car carz0_ 
>         left outer join
>             lot lotz1_ 
>                 on carz0_.loc_code=lotz1_.loc_code
> This is consistent w/ the EJB 3.0 spec (and Glassfish+Toplink) but that's only because the spec doesn't define exacltly how to handle this.  However, that being said, this seems important enough for Hibernate to be able to manage?

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira




More information about the hibernate-issues mailing list