[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-6221) Hibernate throws AnnotationException on column used by multiple overlapping foreign keys
Karsten Wutzke (JIRA)
noreply at atlassian.com
Wed Jun 1 08:29:24 EDT 2011
[ http://opensource.atlassian.com/projects/hibernate/browse/HHH-6221?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=42453#action_42453 ]
Karsten Wutzke commented on HHH-6221:
-------------------------------------
This bug report is a superior description of http://opensource.atlassian.com/projects/hibernate/browse/HHH-5488
Please flag the other as a duplicate of this one.
> 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.
-
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