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

Karsten Wutzke (JIRA) noreply at atlassian.com
Sun May 15 15:56:24 EDT 2011


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