Cannot determine java-type from given member [null] with "properties" in Hibernate 4.2

Description

When a "properties" element is defined in the mapping file, for example:

<properties name="refkey">
<property name="field1" type="java.lang.String" column="column3" not-null="true" length="20" />
<property name="field2" type="java.lang.String" column="column4" not-null="true" />
</properties>

The system throws errors:

14:36:32,052 TRACE [org.hibernate.ejb.metamodel.AttributeFactory] (ServerService Thread Pool – 48) Starting attribute metadata determination [refkey]
14:36:32,052 TRACE [org.hibernate.ejb.metamodel.AttributeFactory] (ServerService Thread Pool – 48) Determined member [null]
14:36:32,052 TRACE [org.hibernate.ejb.metamodel.AttributeFactory] (ServerService Thread Pool – 48) Determined type [name=component[field1,field2], class=org.hibernate.type.EmbeddedComponentType]
14:36:32,053 TRACE [org.hibernate.ejb.metamodel.MetadataContext] (ServerService Thread Pool – 48) Completed entity [org.hibernate.issue.EntityClass1]
14:36:32,053 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool – 48) MSC000001: Failed to start service jboss.persistenceunit."hibernateissue-jar-0.0.1-SNAPSHOT.jar#myPU": org.jboss.msc.service.StartException in service jboss.persistenceunit."hibernateissue-jar-0.0.1-SNAPSHOT.jar#myPU": java.lang.IllegalArgumentException: Cannot determine java-type from given member [null]
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1.run(PersistenceUnitServiceImpl.java:103) [jboss-as-jpa-7.2.1.Final-redhat-10.jar:7.2.1.Final-redhat-10]
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [rt.jar:1.6.0_37]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [rt.jar:1.6.0_37]
at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_37]
at org.jboss.threads.JBossThread.run(JBossThread.java:122) [jboss-threads-2.1.0.Final-redhat-1.jar:2.1.0.Final-redhat-1]
Caused by: java.lang.IllegalArgumentException: Cannot determine java-type from given member [null]
at org.hibernate.ejb.metamodel.AttributeFactory$BaseAttributeMetadata.<init>(AttributeFactory.java:589)
at org.hibernate.ejb.metamodel.AttributeFactory$SingularAttributeMetadataImpl.<init>(AttributeFactory.java:677)
at org.hibernate.ejb.metamodel.AttributeFactory$SingularAttributeMetadataImpl.<init>(AttributeFactory.java:667)
at org.hibernate.ejb.metamodel.AttributeFactory.determineAttributeMetadata(AttributeFactory.java:531)
at org.hibernate.ejb.metamodel.AttributeFactory.buildAttribute(AttributeFactory.java:98)
at org.hibernate.ejb.metamodel.MetadataContext.wrapUp(MetadataContext.java:212)
at org.hibernate.ejb.metamodel.MetamodelImpl.buildMetamodel(MetamodelImpl.java:88)
at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:104)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:920)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:904)
at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:92)
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.createContainerEntityManagerFactory(PersistenceUnitServiceImpl.java:200) [jboss-as-jpa-7.2.1.Final-redhat-10.jar:7.2.1.Final-redhat-10]
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.access$600(PersistenceUnitServiceImpl.java:57) [jboss-as-jpa-7.2.1.Final-redhat-10.jar:7.2.1.Final-redhat-10]
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1.run(PersistenceUnitServiceImpl.java:99) [jboss-as-jpa-7.2.1.Final-redhat-10.jar:7.2.1.Final-redhat-10]
... 4 more

This issue is very similar to https://hibernate.atlassian.net/browse/HHH-4870

But in this case it's really regarding to the <properties> element.

The fix for introduced a new method for Property.
public boolean isSynthetic() {
return false;
}

The SyntheticProperty, Backref and IndexBackref all implemented
@Override
public boolean isSynthetic() {
return true;
}

The "properties" seems to not be interpreted as any of SyntheticProperty, Backref and IndexBackref.

This is the code in org.hibernate.ejb.metamodel.AttributeFactory.java:

@SuppressWarnings({ "unchecked" })
public <X, Y> AttributeImplementor<X, Y> buildAttribute(AbstractManagedType<X> ownerType, Property property) {
if ( property.isSynthetic() ) {
// hide synthetic/virtual properties (fabricated by Hibernate) from the JPA metamodel.
LOG.tracef(
"Skipping synthetic property %s(%s)",
ownerType.getJavaType().getName(),
property.getName()
);
return null;
}
LOG.trace("Building attribute [" + ownerType.getJavaType().getName() + "." + property.getName() + "]");
final AttributeContext<X> attributeContext = wrap( ownerType, property );
final AttributeMetadata<X,Y> attributeMetadata =
determineAttributeMetadata( attributeContext, NORMAL_MEMBER_RESOLVER );
...

Since "properties" is not synthetic, it continue to trigger the call determineAttributeMetadata.

The following the code that throws the error in AttributeFactory.java:

// we can support method or field members here. Is there really any other valid type?
if ( Field.class.isInstance( member ) ) {
declaredType = ( (Field) member ).getType();
}
else if ( Method.class.isInstance( member ) ) {
declaredType = ( (Method) member ).getReturnType();
}
else {
throw new IllegalArgumentException( "Cannot determine java-type from given member [" + member + "]" );
}

Obviously, there's no any "type" associated with the "properties":
<properties name="refkey">

I think the issue here is why the "properties" is not interpreted as synthetic so that it can escape the call determineAttributeMetadata.

I'm attaching a simple maven project with deployment archive as well as the server.log for you reference.

Environment

None

Status

Assignee

Brett Meyer

Reporter

Gary Hu

Fix versions

Labels

None

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Affects versions

4.2.0.Final

Priority

Major
Configure