14743

Hibernate: bug when mapping a reference to an alternative/natural key column of a sub table?

Question:

The original question stems from this question:

<a href="https://stackoverflow.com/questions/5784272/why-is-this-jpa-2-0-mapping-giving-me-an-error-in-eclipse-jboss-tools" rel="nofollow">Why is this JPA 2.0 mapping giving me an error in Eclipse/JBoss Tools?</a>

As you can see this constellation also freaks out the Eclipse Dali JPA validator. The JPA spec seems to allow this as seen here (somewhat reliable):

<a href="https://stackoverflow.com/questions/5818373/jpa-does-the-jpa-specification-allow-references-to-non-primary-key-columns" rel="nofollow">Does the JPA specification allow references to non-primary key columns?</a>

The exact code posted in the first question also raises a Hibernate MappingException:

Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: geoareas] 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.geoareas.Main.main(Main.java:69) Caused by: org.hibernate.MappingException: property [_tld_geoareas_model_Zip__identifierMapper.country] not found on entity [tld.geoareas.model.Country] at org.hibernate.mapping.PersistentClass.getRecursiveProperty(PersistentClass.java:378) at org.hibernate.cfg.annotations.TableBinder.bindFk(TableBinder.java:414) at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:115) at org.hibernate.cfg.Configuration.processEndOfQueue(Configuration.java:1550) at org.hibernate.cfg.Configuration.processFkSecondPassInOrder(Configuration.java:1473) at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1389) 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 Caused by: org.hibernate.MappingException: property [_tld_geoareas_model_Zip__identifierMapper.country] not found on entity [tld.geoareas.model.Country] at org.hibernate.mapping.PersistentClass.getRecursiveProperty(PersistentClass.java:424) at org.hibernate.mapping.PersistentClass.getRecursiveProperty(PersistentClass.java:375) ... 15 more

I'm especially irritated by the "recursive property". After all, it's just a simple single-column reference to a UNIQUE, NOT NULL CHAR(2) column of a GeoAreas sub table Countries. Note the inheritance might have some impact here, but it's still not overly complicated IMHO.

So, is this a Hibernate bug?

Answer1:

Answering my own question:

It's not a bug in Hibernate. It's the JPA 2.0 spec that prohibits references to non-PK columns when used as a derived identifier at the same time. See my other answer here for more details:

<a href="https://stackoverflow.com/questions/5784272/why-is-this-jpa-2-0-mapping-giving-me-an-error-in-eclipse-jboss-tools" rel="nofollow">Why is this JPA 2.0 mapping giving me an error in Eclipse/JBoss Tools?</a>

Note it's also causing a mapping exception with EclipseLink (you just get a more meaningful stack trace):

Exception Description: The derived composite primary key attribute [country] of type [java.lang.String] from [tld.geoareas.model.ZipId] should be of the same type as its parent id field from [tld.geoareas.model.Country]. That is, it should be of type [java.lang.Integer]. at org.eclipse.persistence.exceptions.ValidationException.invalidDerivedCompositePKAttribute(ValidationException.java:1134) at org.eclipse.persistence.internal.jpa.metadata.MetadataDescriptor.validateDerivedPKClassId(MetadataDescriptor.java:1817) at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ObjectAccessor.processId(ObjectAccessor.java:450) at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ObjectAccessor.processOwningMappingKeys(ObjectAccessor.java:659) at org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ManyToOneAccessor.process(ManyToOneAccessor.java:110) at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.ClassAccessor.processDerivedId(ClassAccessor.java:1409) at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.processDerivedId(EntityAccessor.java:823) at org.eclipse.persistence.internal.jpa.metadata.MetadataProject.processAccessorsWithDerivedIDs(MetadataProject.java:1294) at org.eclipse.persistence.internal.jpa.metadata.MetadataProject.processStage3(MetadataProject.java:1560) at org.eclipse.persistence.internal.jpa.metadata.MetadataProcessor.processORMMetadata(MetadataProcessor.java:484) at org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processORMetadata(PersistenceUnitProcessor.java:453) at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:1080) ... 6 more

Recommend

  • How to hide RSS page from everyone except FeedBurner
  • Java package naming and non .com domains
  • Socket.IO client library gives “welcome to socket.io” message
  • How do I use multiple databases with JPA?
  • How to update data in Redis and MySQL at the same time?
  • How to fix: The return type of an async method must be void, Task or Task [AppName]
  • dynamic server time
  • How do I get NHibernate to save an entity if I assign it an ID, but generate one otherwise?
  • Applying custom annotation advice to spring data jpa repository
  • Trouble linking libusb using Cmake
  • Perl function name clash
  • JPA/Hibernate - Entity name seems to be important. If I rename to “Bob” works fine
  • What is the best way to debug Bootstrap.groovy?
  • What is this strange character in chrome's resource css viewer?
  • Symfony2 - Doctrine - no changeset in post update
  • Doctrine/Symfony entity generator and generating entity from one table
  • Can't remove headers after they are sent
  • How to getText() from the input field of an angularjs Application
  • Combining two different ActiveRecord collections into one
  • Why cepheus don't send int without quotes to orion?
  • GAE: Way to get reference to an HttpSession from its ID?
  • Angularjs pass function from Controller to Directive (or call controller function from directive) -
  • Django invalid literal for int() with base 10
  • Force show.bind execution
  • ViewController With Transparent Background Entering Current ViewController With Push Transition
  • how to save the state in userdefaults of accessory checkmark-iphone
  • Eloquent update method change created_at timestamp
  • Database structure design with variable amounts of fields
  • The plugin 'org.apache.maven.plugins:maven-jboss-as-plugin' does not exist or no valid ver
  • How do I fake an specific browser client when using Java's Net library?
  • How to get a value (ex: baseURL) in every Karate feature?
  • Possible to stop flickering java tooltip in heavyweight mode?
  • output of program is not same as passed argument
  • Akka Routing: Reply's send to router ends up as dead letters
  • unknown Exception android
  • MATLAB: Piecewise function in curve fitting toolbox using fittype
  • Checking variable from a different class in C#
  • Why is Django giving me: 'first_name' is an invalid keyword argument for this function?
  • Binding checkboxes to object values in AngularJs
  • How can I use `wmic` in a Windows PE script?