[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-6221) Hibernate throws AnnotationException on column used by multiple overlapping foreign keys

Anne Buit (JIRA) noreply at atlassian.com
Mon Aug 29 04:43:02 EDT 2011


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-6221?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=43372#comment-43372 ] 

Anne Buit commented on HHH-6221:
--------------------------------

Two more topics on the Hibernate forum about this issue:
https://forum.hibernate.org/viewtopic.php?f=1&t=1011195
https://forum.hibernate.org/viewtopic.php?f=1&t=1011210

Is there some kind of work-around available?

> Hibernate throws AnnotationException on column used by multiple overlapping foreign keys
> ----------------------------------------------------------------------------------------
>
>                 Key: HHH-6221
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-6221
>             Project: Hibernate Core
>          Issue Type: Bug
>          Components: annotations, core, entity-manager
>    Affects Versions: 3.6.0
>         Environment: Hibernate 3.6.0, HSQLDB 2, JavaSE (probably all Hibernate versions to date affected)
>            Reporter: Karsten Wutzke
>            Priority: Critical
>         Attachments: overlapping-fks-hib-broken.zip
>
>
> Here's a view of the design:
> !http://www.kawoolutions.com/media/postareas-min.png!
> Simple logic: two tables use composite PKs and use a country_code column in the PK. PostAreas is a simple join table so its PK is comprised of the two linked tables' PK columns. Problem: both FKs in PostAreas use country_code to produce an overlap.
> This is per se nothing special, but in the context of JPA it is: there may be only one writable mapping in the @JoinColumn annotations, all other must be set to read-only, that is _insertable = false, updatable = false_.
> Here are the (incomplete) mappings (full SSCCE attached):
> {code:java}
> @Entity
> @Table(name = "Zips")
> @IdClass(value = ZipId.class)
> public class Zip implements Serializable
> {
>     @Id
>     @Column(name = "country_code")
>     private String countryCode;
>     @Id
>     @Column(name = "code")
>     private String code;
>     ...
> }
> {code}
> {code:java}
> public class ZipId implements Serializable
> {
>     private String countryCode;
>     private String code;
>     ...
> }
> {code}
> {code:java}
> @Entity
> @Table(name = "Cities")
> @IdClass(value = CityId.class)
> public class City implements Serializable
> {
>     @Id
>     @Column(name = "country_code")
>     private String countryCode;
>     @Id
>     @Column(name = "state_code")
>     private String stateCode;
>     @Id
>     @Column(name = "name")
>     private String name;
>     ...
> }
> {code}
> {code:java}
> public class CityId implements Serializable
> {
>     private String countryCode;
>     private String stateCode;
>     private String name;
>     ...
> }
> {code}
> {code:java}
> @Entity
> @Table(name = "PostAreas")
> @IdClass(value = PostAreaId.class)
> public class PostArea implements Serializable
> {
>     @Id
>     @Column(name = "country_code", insertable = false, updatable = false)
>     private String countryCode;
>     @Id
>     @Column(name = "state_code", insertable = false, updatable = false)
>     private String stateCode;
>     @Id
>     @Column(name = "zip_code", insertable = false, updatable = false)
>     private String zipCode;
>     @Id
>     @Column(name = "city_name", insertable = false, updatable = false)
>     private String cityName;
>     @ManyToOne
>     @JoinColumns(value = {
>         @JoinColumn(name = "country_code", referencedColumnName = "country_code"),
>         @JoinColumn(name = "zip_code", referencedColumnName = "code")
>     })
>     private Zip zip;
>     @ManyToOne
>     @JoinColumns(value = {
>         @JoinColumn(name = "country_code", referencedColumnName = "country_code", insertable = false, updatable = false), // <- !!!
>         @JoinColumn(name = "state_code", referencedColumnName = "state_code"),
>         @JoinColumn(name = "city_name", referencedColumnName = "name")
>     })
>     private City city;
>     ...
> }
> {code}
> {code:java}
> public class PostAreaId implements Serializable
> {
>     private String countryCode;
>     private String stateCode;
>     private String zipCode;
>     private String cityName;
>     ...
> }
> {code}
> Looking at PostArea.city (*scroll down in the PostArea code box!*): the @JoinColumn for country_code is set to read-only on City and to writable on Zip. However, when running this from a JavaSE test app Hibernate fails with an AnnotationException:
> {code}
> Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: postareas] Unable to configure EntityManagerFactory
>     at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:374)
>     at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:56)
>     at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:48)
>     at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:32)
>     at tld.postareas.Main.main(Main.java:38)
> Caused by: org.hibernate.AnnotationException: Mixing insertable and non insertable columns in a property is not allowed: tld.postareas.model.PostAreacity
>     at org.hibernate.cfg.Ejb3Column.checkPropertyConsistency(Ejb3Column.java:563)
>     at org.hibernate.cfg.AnnotationBinder.bindManyToOne(AnnotationBinder.java:2703)
>     at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1600)
>     at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:796)
>     at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:707)
>     at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3977)
>     at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3931)
>     at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1368)
>     at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1345)
>     at org.hibernate.ejb.Ejb3Configuration.buildMappings(Ejb3Configuration.java:1477)
>     at org.hibernate.ejb.EventListenerConfigurator.configure(EventListenerConfigurator.java:193)
>     at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:1096)
>     at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:278)
>     at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:362)
>     ... 4 more
> {code}
> When mapping a table that uses the same column in two or more foreign keys, only one of the relationships' @JoinColumn annotations may be tagged as writable. However, mixing read-only and writable in a multi-column relationship *must* be supported.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the hibernate-issues mailing list