HHH-5794 Enhance the test to cover additional mapping elements, and implement support for them.

This commit is contained in:
David M. Carr 2010-12-15 09:53:54 -05:00 committed by Hardy Ferentschik
parent ce9343bbd2
commit 0c23e5870c
4 changed files with 167 additions and 22 deletions

View File

@ -47,6 +47,7 @@ import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides; import javax.persistence.AttributeOverrides;
import javax.persistence.Basic; import javax.persistence.Basic;
import javax.persistence.CascadeType; import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.ColumnResult; import javax.persistence.ColumnResult;
import javax.persistence.DiscriminatorColumn; import javax.persistence.DiscriminatorColumn;
@ -78,6 +79,11 @@ import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
import javax.persistence.MapKey; import javax.persistence.MapKey;
import javax.persistence.MapKeyClass; import javax.persistence.MapKeyClass;
import javax.persistence.MapKeyColumn;
import javax.persistence.MapKeyEnumerated;
import javax.persistence.MapKeyJoinColumn;
import javax.persistence.MapKeyJoinColumns;
import javax.persistence.MapKeyTemporal;
import javax.persistence.MappedSuperclass; import javax.persistence.MappedSuperclass;
import javax.persistence.NamedNativeQueries; import javax.persistence.NamedNativeQueries;
import javax.persistence.NamedNativeQuery; import javax.persistence.NamedNativeQuery;
@ -86,6 +92,7 @@ import javax.persistence.NamedQuery;
import javax.persistence.OneToMany; import javax.persistence.OneToMany;
import javax.persistence.OneToOne; import javax.persistence.OneToOne;
import javax.persistence.OrderBy; import javax.persistence.OrderBy;
import javax.persistence.OrderColumn;
import javax.persistence.PostLoad; import javax.persistence.PostLoad;
import javax.persistence.PostPersist; import javax.persistence.PostPersist;
import javax.persistence.PostRemove; import javax.persistence.PostRemove;
@ -113,6 +120,7 @@ import javax.persistence.ElementCollection;
import org.dom4j.Attribute; import org.dom4j.Attribute;
import org.dom4j.Element; import org.dom4j.Element;
import org.hibernate.AnnotationException; import org.hibernate.AnnotationException;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CollectionOfElements; import org.hibernate.annotations.CollectionOfElements;
import org.hibernate.annotations.Columns; import org.hibernate.annotations.Columns;
import org.hibernate.annotations.common.annotationfactory.AnnotationDescriptor; import org.hibernate.annotations.common.annotationfactory.AnnotationDescriptor;
@ -196,9 +204,16 @@ public class JPAOverridenAnnotationReader implements AnnotationReader {
annotationToXml.put( JoinTable.class, "join-table" ); annotationToXml.put( JoinTable.class, "join-table" );
annotationToXml.put( JoinColumn.class, "join-column" ); annotationToXml.put( JoinColumn.class, "join-column" );
annotationToXml.put( JoinColumns.class, "join-column" ); annotationToXml.put( JoinColumns.class, "join-column" );
annotationToXml.put( CollectionTable.class, "collection-table" );
annotationToXml.put( MapKey.class, "map-key" ); annotationToXml.put( MapKey.class, "map-key" );
annotationToXml.put( MapKeyClass.class, "map-key-class" ); annotationToXml.put( MapKeyClass.class, "map-key-class" );
annotationToXml.put( MapKeyTemporal.class, "map-key-temporal" );
annotationToXml.put( MapKeyEnumerated.class, "map-key-enumerated" );
annotationToXml.put( MapKeyColumn.class, "map-key-column" );
annotationToXml.put( MapKeyJoinColumn.class, "map-key-join-column" );
annotationToXml.put( MapKeyJoinColumns.class, "map-key-join-column" );
annotationToXml.put( OrderBy.class, "order-by" ); annotationToXml.put( OrderBy.class, "order-by" );
annotationToXml.put( OrderColumn.class, "order-column" );
annotationToXml.put( EntityListeners.class, "entity-listeners" ); annotationToXml.put( EntityListeners.class, "entity-listeners" );
annotationToXml.put( PrePersist.class, "pre-persist" ); annotationToXml.put( PrePersist.class, "pre-persist" );
annotationToXml.put( PreRemove.class, "pre-remove" ); annotationToXml.put( PreRemove.class, "pre-remove" );
@ -660,10 +675,17 @@ public class JPAOverridenAnnotationReader implements AnnotationReader {
Annotation annotation = getPrimaryKeyJoinColumns( element, defaults ); Annotation annotation = getPrimaryKeyJoinColumns( element, defaults );
addIfNotNull( annotationList, annotation ); addIfNotNull( annotationList, annotation );
copyBooleanAttribute( ad, element, "optional" ); copyBooleanAttribute( ad, element, "optional" );
copyBooleanAttribute( ad, element, "orphan-removal" );
copyStringAttribute( ad, element, "mapped-by", false ); copyStringAttribute( ad, element, "mapped-by", false );
getOrderBy( annotationList, element ); getOrderBy( annotationList, element );
//TODO: support order-column
getMapKey( annotationList, element ); getMapKey( annotationList, element );
getMapKeyClass( annotationList, element, defaults ); getMapKeyClass( annotationList, element, defaults );
//TODO: support map-key-temporal
//TODO: support map-key-enumerated
//TODO: support map-key-attribute-override
getMapKeyColumn(annotationList, element);
//TODO: support map-key-join-column
annotationList.add( AnnotationFactory.create( ad ) ); annotationList.add( AnnotationFactory.create( ad ) );
getAccessType( annotationList, element ); getAccessType( annotationList, element );
} }
@ -684,8 +706,22 @@ public class JPAOverridenAnnotationReader implements AnnotationReader {
addIfNotNull( annotationList, annotation ); addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( MapKey.class ); annotation = getJavaAnnotation( MapKey.class );
addIfNotNull( annotationList, annotation ); addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( MapKeyClass.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( MapKeyTemporal.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( MapKeyEnumerated.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( MapKeyColumn.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( MapKeyJoinColumn.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( MapKeyJoinColumns.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( OrderBy.class ); annotation = getJavaAnnotation( OrderBy.class );
addIfNotNull( annotationList, annotation ); addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( OrderColumn.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( AttributeOverride.class ); annotation = getJavaAnnotation( AttributeOverride.class );
addIfNotNull( annotationList, annotation ); addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( AttributeOverrides.class ); annotation = getJavaAnnotation( AttributeOverrides.class );
@ -704,21 +740,37 @@ public class JPAOverridenAnnotationReader implements AnnotationReader {
addIfNotNull( annotationList, annotation ); addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( Columns.class ); annotation = getJavaAnnotation( Columns.class );
addIfNotNull( annotationList, annotation ); addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( Cascade.class );
addIfNotNull( annotationList, annotation );
} }
else if ( isJavaAnnotationPresent( ElementCollection.class ) ) { //JPA2 else if ( isJavaAnnotationPresent( ElementCollection.class ) ) { //JPA2
annotation = overridesDefaultsInJoinTable( getJavaAnnotation( ElementCollection.class ), defaults ); annotation = overridesDefaultsInJoinTable( getJavaAnnotation( ElementCollection.class ), defaults );
addIfNotNull( annotationList, annotation ); addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( JoinColumn.class ); annotation = getJavaAnnotation( OrderBy.class );
addIfNotNull( annotationList, annotation ); addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( JoinColumns.class ); annotation = getJavaAnnotation( OrderColumn.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( PrimaryKeyJoinColumn.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( PrimaryKeyJoinColumns.class );
addIfNotNull( annotationList, annotation ); addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( MapKey.class ); annotation = getJavaAnnotation( MapKey.class );
addIfNotNull( annotationList, annotation ); addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( OrderBy.class ); annotation = getJavaAnnotation( MapKeyClass.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( MapKeyTemporal.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( MapKeyEnumerated.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( MapKeyColumn.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( MapKeyJoinColumn.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( MapKeyJoinColumns.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( Column.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( Temporal.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( Enumerated.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( Lob.class );
addIfNotNull( annotationList, annotation ); addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( AttributeOverride.class ); annotation = getJavaAnnotation( AttributeOverride.class );
addIfNotNull( annotationList, annotation ); addIfNotNull( annotationList, annotation );
@ -728,15 +780,7 @@ public class JPAOverridenAnnotationReader implements AnnotationReader {
addIfNotNull( annotationList, annotation ); addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( AssociationOverrides.class ); annotation = getJavaAnnotation( AssociationOverrides.class );
addIfNotNull( annotationList, annotation ); addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( Lob.class ); annotation = getJavaAnnotation( CollectionTable.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( Enumerated.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( Temporal.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( Column.class );
addIfNotNull( annotationList, annotation );
annotation = getJavaAnnotation( Columns.class );
addIfNotNull( annotationList, annotation ); addIfNotNull( annotationList, annotation );
} }
else if ( isJavaAnnotationPresent( CollectionOfElements.class ) ) { //legacy Hibernate else if ( isJavaAnnotationPresent( CollectionOfElements.class ) ) { //legacy Hibernate
@ -795,19 +839,37 @@ public class JPAOverridenAnnotationReader implements AnnotationReader {
} }
} }
// TODO: Complete parsing of all element-collection related xml
private void getElementCollection(List<Annotation> annotationList, XMLContext.Default defaults) { private void getElementCollection(List<Annotation> annotationList, XMLContext.Default defaults) {
for ( Element element : elementsForProperty ) { for ( Element element : elementsForProperty ) {
if ( "element-collection".equals( element.getName() ) ) { if ( "element-collection".equals( element.getName() ) ) {
AnnotationDescriptor ad = new AnnotationDescriptor( ElementCollection.class ); AnnotationDescriptor ad = new AnnotationDescriptor( ElementCollection.class );
addTargetClass( element, ad, "target-class", defaults ); addTargetClass( element, ad, "target-class", defaults );
getFetchType( ad, element );
getOrderBy( annotationList, element );
//TODO: support order-column
getMapKey( annotationList, element );
getMapKeyClass( annotationList, element, defaults );
//TODO: support map-key-temporal
//TODO: support map-key-enumerated
//TODO: support map-key-attribute-override
getMapKeyColumn(annotationList, element);
//TODO: support map-key-join-column
Annotation annotation = getColumn(element.element( "column" ), false, element);
addIfNotNull(annotationList, annotation);
getTemporal(annotationList, element);
getEnumerated(annotationList, element);
getLob(annotationList, element);
annotation = getAttributeOverrides( element, defaults );
addIfNotNull( annotationList, annotation );
annotation = getAssociationOverrides( element, defaults );
addIfNotNull( annotationList, annotation );
getCollectionTable(annotationList, element, defaults);
annotationList.add( AnnotationFactory.create( ad ) ); annotationList.add( AnnotationFactory.create( ad ) );
getAccessType( annotationList, element ); getAccessType( annotationList, element );
} }
} }
} }
private void getOrderBy(List<Annotation> annotationList, Element element) { private void getOrderBy(List<Annotation> annotationList, Element element) {
Element subelement = element != null ? element.element( "order-by" ) : null; Element subelement = element != null ? element.element( "order-by" ) : null;
if ( subelement != null ) { if ( subelement != null ) {
@ -828,6 +890,24 @@ public class JPAOverridenAnnotationReader implements AnnotationReader {
} }
} }
private void getMapKeyColumn(List<Annotation> annotationList, Element element) {
Element subelement = element != null ? element.element( "map-key-column" ) : null;
if ( subelement != null ) {
AnnotationDescriptor ad = new AnnotationDescriptor( MapKeyColumn.class );
copyStringAttribute( ad, subelement, "name", false );
copyBooleanAttribute( ad, subelement, "unique" );
copyBooleanAttribute( ad, subelement, "nullable" );
copyBooleanAttribute( ad, subelement, "insertable" );
copyBooleanAttribute( ad, subelement, "updatable" );
copyStringAttribute( ad, subelement, "column-definition", false );
copyStringAttribute( ad, subelement, "table", false );
copyIntegerAttribute( ad, subelement, "length" );
copyIntegerAttribute( ad, subelement, "precision" );
copyIntegerAttribute( ad, subelement, "scale" );
annotationList.add( AnnotationFactory.create( ad ) );
}
}
private void getMapKeyClass(List<Annotation> annotationList, Element element, XMLContext.Default defaults) { private void getMapKeyClass(List<Annotation> annotationList, Element element, XMLContext.Default defaults) {
String nodeName = "map-key-class"; String nodeName = "map-key-class";
Element subelement = element != null ? element.element( nodeName ) : null; Element subelement = element != null ? element.element( nodeName ) : null;
@ -2064,6 +2144,30 @@ public class JPAOverridenAnnotationReader implements AnnotationReader {
return null; return null;
} }
} }
private void getCollectionTable(List<Annotation> annotationList, Element element, XMLContext.Default defaults) {
Element subelement = element != null ? element.element( "collection-table" ) : null;
if ( subelement != null ) {
AnnotationDescriptor annotation = new AnnotationDescriptor( CollectionTable.class );
copyStringAttribute( annotation, subelement, "name", false );
copyStringAttribute( annotation, subelement, "catalog", false );
if ( StringHelper.isNotEmpty( defaults.getCatalog() )
&& StringHelper.isEmpty( (String) annotation.valueOf( "catalog" ) ) ) {
annotation.setValue( "catalog", defaults.getCatalog() );
}
copyStringAttribute( annotation, subelement, "schema", false );
if ( StringHelper.isNotEmpty( defaults.getSchema() )
&& StringHelper.isEmpty( (String) annotation.valueOf( "schema" ) ) ) {
annotation.setValue( "schema", defaults.getSchema() );
}
JoinColumn[] joinColumns = getJoinColumns( subelement, false );
if ( joinColumns.length > 0 ) {
annotation.setValue( "joinColumns", joinColumns );
}
buildUniqueConstraints( annotation, subelement );
annotationList.add( AnnotationFactory.create( annotation ) );
}
}
private void overridesDefaultInSecondaryTable( private void overridesDefaultInSecondaryTable(
SecondaryTable secTableAnn, XMLContext.Default defaults, List<SecondaryTable> secondaryTables SecondaryTable secTableAnn, XMLContext.Default defaults, List<SecondaryTable> secondaryTables

View File

@ -1,10 +1,22 @@
package org.hibernate.test.annotations.xml.ejb3; package org.hibernate.test.annotations.xml.ejb3;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.persistence.MapKeyClass; //import javax.persistence.CollectionTable;
//import javax.persistence.Column;
//import javax.persistence.ElementCollection;
//import javax.persistence.JoinColumn;
//import javax.persistence.MapKeyClass;
//import javax.persistence.MapKeyColumn;
public class Company { public class Company {
int id; int id;
Map organization; Map organization = new HashMap();
// @ElementCollection(targetClass=String.class)
// @MapKeyClass(String.class)
// @MapKeyColumn(name="room_number")
// @Column(name="phone_extension")
// @CollectionTable(name="phone_extension_lookup", joinColumns={@JoinColumn(name="company_id", referencedColumnName="id")})
Map conferenceRoomExtensions = new HashMap();
} }

View File

@ -3,12 +3,18 @@ package org.hibernate.test.annotations.xml.ejb3;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction; import org.hibernate.Transaction;
import org.hibernate.dialect.PostgreSQLDialect; import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metadata.CollectionMetadata;
import org.hibernate.persister.collection.BasicCollectionPersister;
import org.hibernate.test.annotations.TestCase; import org.hibernate.test.annotations.TestCase;
import org.hibernate.testing.junit.SkipForDialect; import org.hibernate.testing.junit.SkipForDialect;
import org.hibernate.tuple.entity.EntityMetamodel;
/** /**
* @author Emmanuel Bernard * @author Emmanuel Bernard
@ -68,13 +74,28 @@ public class Ejb3XmlTest extends TestCase {
s.close(); s.close();
} }
public void testMapKeyClass() throws Exception { public void testMapXMLSupport() throws Exception {
Session s = openSession(); Session s = openSession();
SessionFactory sf = s.getSessionFactory();
Transaction tx = s.beginTransaction(); Transaction tx = s.beginTransaction();
// Verify that we can persist an object with a couple Map mappings
VicePresident vpSales = new VicePresident();
vpSales.name = "Dwight";
Company company = new Company(); Company company = new Company();
company.conferenceRoomExtensions.put("8932", "x1234");
company.organization.put("sales", vpSales);
s.persist( company ); s.persist( company );
s.flush(); s.flush();
s.clear(); s.clear();
// For the element-collection, check that the orm.xml entries are honored.
// This includes: map-key-column/column/collection-table/join-column
BasicCollectionPersister confRoomMeta = (BasicCollectionPersister) sf.getCollectionMetadata(Company.class.getName() + ".conferenceRoomExtensions");
assertEquals("company_id", confRoomMeta.getKeyColumnNames()[0]);
assertEquals("phone_extension", confRoomMeta.getElementColumnNames()[0]);
assertEquals("room_number", confRoomMeta.getIndexColumnNames()[0]);
assertEquals("phone_extension_lookup", confRoomMeta.getTableName());
tx.rollback(); tx.rollback();
s.close(); s.close();
} }

View File

@ -11,6 +11,14 @@
<one-to-many name="organization" target-entity="VicePresident"> <one-to-many name="organization" target-entity="VicePresident">
<map-key-class class="java.lang.String" /> <map-key-class class="java.lang.String" />
</one-to-many> </one-to-many>
<element-collection name="conferenceRoomExtensions" target-class="java.lang.String">
<map-key-class class="java.lang.String" />
<map-key-column name="room_number" />
<column name="phone_extension"/>
<collection-table name="phone_extension_lookup">
<join-column name="company_id" referenced-column-name="id" />
</collection-table>
</element-collection>
</attributes> </attributes>
</entity> </entity>
<entity class="VicePresident" access="FIELD" metadata-complete="true"> <entity class="VicePresident" access="FIELD" metadata-complete="true">