HHH-7571 Starting to process @JoinTable and @CollectionTable
Moving JoinColumn processing into association attribute Making anonymous ExplicitHibernateTypeSource implementation its own class
This commit is contained in:
parent
d661c3823d
commit
ebcc59f0a1
|
@ -22,7 +22,7 @@ public class BasicPluralAttributeElementSourceImpl implements BasicPluralAttribu
|
|||
|
||||
@Override
|
||||
public ExplicitHibernateTypeSource getExplicitHibernateTypeSource() {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
return new ExplicitHibernateTypeSourceImpl( associationAttribute );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -42,7 +42,7 @@ public class BasicPluralAttributeElementSourceImpl implements BasicPluralAttribu
|
|||
|
||||
@Override
|
||||
public List<RelationalValueSource> relationalValueSources() {
|
||||
List<RelationalValueSource> valueSources = new ArrayList<RelationalValueSource>( );
|
||||
List<RelationalValueSource> valueSources = new ArrayList<RelationalValueSource>();
|
||||
if ( !associationAttribute.getColumnValues().isEmpty() ) {
|
||||
for ( Column columnValues : associationAttribute.getColumnValues() ) {
|
||||
valueSources.add( new ColumnSourceImpl( associationAttribute, null, columnValues ) );
|
||||
|
@ -51,6 +51,7 @@ public class BasicPluralAttributeElementSourceImpl implements BasicPluralAttribu
|
|||
return valueSources;
|
||||
}
|
||||
|
||||
// TODO - these values are also hard coded in the hbm version of this source implementation. Do we really need them? (HF)
|
||||
@Override
|
||||
public boolean areValuesIncludedInInsertByDefault() {
|
||||
return true;
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.metamodel.internal.source.annotations;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.metamodel.internal.source.annotations.attribute.AssociationAttribute;
|
||||
import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource;
|
||||
|
||||
/**
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class ExplicitHibernateTypeSourceImpl implements ExplicitHibernateTypeSource {
|
||||
private final AssociationAttribute attribute;
|
||||
|
||||
public ExplicitHibernateTypeSourceImpl(AssociationAttribute attribute) {
|
||||
this.attribute = attribute;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return attribute.getHibernateTypeResolver().getExplicitHibernateTypeName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getParameters() {
|
||||
return attribute.getHibernateTypeResolver().getExplicitHibernateTypeParameters();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -61,17 +61,7 @@ public class PluralAttributeSourceImpl implements PluralAttributeSource, Orderab
|
|||
this.nature = resolveAttributeNature();
|
||||
this.keySource = new PluralAttributeKeySourceImpl( attribute );
|
||||
this.elementSource = determineElementSource();
|
||||
this.typeSource = new ExplicitHibernateTypeSource() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return attribute.getHibernateTypeResolver().getExplicitHibernateTypeName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getParameters() {
|
||||
return attribute.getHibernateTypeResolver().getExplicitHibernateTypeParameters();
|
||||
}
|
||||
};
|
||||
this.typeSource = new ExplicitHibernateTypeSourceImpl( attribute );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.internal.source.annotations.attribute;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -61,14 +63,12 @@ public class AssociationAttribute extends MappedAttribute {
|
|||
private final boolean isOptional;
|
||||
private final boolean isLazy;
|
||||
private final boolean isOrphanRemoval;
|
||||
// todo FetchMode is currently used in the persisters. This will probably get replaced bt FetchStyle and FetchTiming
|
||||
private final FetchMode fetchMode;
|
||||
private final FetchStyle fetchStyle;
|
||||
private final boolean mapsId;
|
||||
private final String referencedIdAttributeName;
|
||||
|
||||
private boolean isInsertable = true;
|
||||
private boolean isUpdatable = true;
|
||||
private final List<Column> joinColumnValues;
|
||||
private final boolean definesExplicitJoinTable;
|
||||
private AttributeTypeResolver resolver;
|
||||
|
||||
public static AssociationAttribute createAssociationAttribute(
|
||||
|
@ -78,11 +78,17 @@ public class AssociationAttribute extends MappedAttribute {
|
|||
String accessType,
|
||||
Map<DotName, List<AnnotationInstance>> annotations,
|
||||
EntityBindingContext context) {
|
||||
return new AssociationAttribute( name, attributeType, attributeType, attributeNature, accessType, annotations, context );
|
||||
return new AssociationAttribute(
|
||||
name,
|
||||
attributeType,
|
||||
attributeType,
|
||||
attributeNature,
|
||||
accessType,
|
||||
annotations,
|
||||
context
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
AssociationAttribute(
|
||||
String name,
|
||||
Class<?> attributeType,
|
||||
|
@ -106,11 +112,14 @@ public class AssociationAttribute extends MappedAttribute {
|
|||
this.isLazy = determineIsLazy( associationAnnotation );
|
||||
this.isOrphanRemoval = determineOrphanRemoval( associationAnnotation );
|
||||
this.cascadeTypes = determineCascadeTypes( associationAnnotation );
|
||||
this.joinColumnValues = determineJoinColumnAnnotations( annotations );
|
||||
|
||||
this.fetchMode = determineFetchMode();
|
||||
this.fetchStyle = determineFetchStyle();
|
||||
this.referencedIdAttributeName = determineMapsId();
|
||||
this.mapsId = referencedIdAttributeName != null;
|
||||
|
||||
this.definesExplicitJoinTable = determineExplicitJoinTable( annotations );
|
||||
}
|
||||
|
||||
public boolean isIgnoreNotFound() {
|
||||
|
@ -149,6 +158,14 @@ public class AssociationAttribute extends MappedAttribute {
|
|||
return mapsId;
|
||||
}
|
||||
|
||||
public List<Column> getJoinColumnValues() {
|
||||
return joinColumnValues;
|
||||
}
|
||||
|
||||
public boolean definesExplicitJoinTable() {
|
||||
return definesExplicitJoinTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeTypeResolver getHibernateTypeResolver() {
|
||||
if ( resolver == null ) {
|
||||
|
@ -169,12 +186,12 @@ public class AssociationAttribute extends MappedAttribute {
|
|||
|
||||
@Override
|
||||
public boolean isInsertable() {
|
||||
return isInsertable;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdatable() {
|
||||
return isUpdatable;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -316,6 +333,77 @@ public class AssociationAttribute extends MappedAttribute {
|
|||
}
|
||||
return JandexHelper.getValue( mapsIdAnnotation, "value", String.class );
|
||||
}
|
||||
|
||||
private List<Column> determineJoinColumnAnnotations(Map<DotName, List<AnnotationInstance>> annotations) {
|
||||
ArrayList<Column> joinColumns = new ArrayList<Column>();
|
||||
|
||||
// single @JoinColumn
|
||||
AnnotationInstance joinColumnAnnotation = JandexHelper.getSingleAnnotation(
|
||||
annotations,
|
||||
JPADotNames.JOIN_COLUMN
|
||||
);
|
||||
if ( joinColumnAnnotation != null ) {
|
||||
joinColumns.add( new Column( joinColumnAnnotation ) );
|
||||
}
|
||||
|
||||
// @JoinColumns
|
||||
AnnotationInstance joinColumnsAnnotation = JandexHelper.getSingleAnnotation(
|
||||
annotations,
|
||||
JPADotNames.JOIN_COLUMNS
|
||||
);
|
||||
if ( joinColumnsAnnotation != null ) {
|
||||
List<AnnotationInstance> columnsList = Arrays.asList(
|
||||
JandexHelper.getValue( joinColumnsAnnotation, "value", AnnotationInstance[].class )
|
||||
);
|
||||
for ( AnnotationInstance annotation : columnsList ) {
|
||||
joinColumns.add( new Column( annotation ) );
|
||||
}
|
||||
}
|
||||
joinColumns.trimToSize();
|
||||
return joinColumns;
|
||||
}
|
||||
|
||||
private boolean determineExplicitJoinTable(Map<DotName, List<AnnotationInstance>> annotations) {
|
||||
AnnotationInstance collectionTableAnnotation = JandexHelper.getSingleAnnotation(
|
||||
annotations,
|
||||
JPADotNames.COLLECTION_TABLE
|
||||
);
|
||||
|
||||
AnnotationInstance joinTableAnnotation = JandexHelper.getSingleAnnotation(
|
||||
annotations,
|
||||
JPADotNames.JOIN_TABLE
|
||||
);
|
||||
|
||||
// sanity checks
|
||||
if ( collectionTableAnnotation != null && joinTableAnnotation != null ) {
|
||||
throw new MappingException(
|
||||
"@CollectionTable and JoinTable specified on the same attribute",
|
||||
getContext().getOrigin()
|
||||
);
|
||||
}
|
||||
|
||||
if ( collectionTableAnnotation != null ) {
|
||||
if ( JandexHelper.getSingleAnnotation( annotations, JPADotNames.ELEMENT_COLLECTION ) == null ) {
|
||||
throw new MappingException(
|
||||
"@CollectionTable annotation without a @ElementCollection",
|
||||
getContext().getOrigin()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( joinTableAnnotation != null ) {
|
||||
if ( JandexHelper.getSingleAnnotation( annotations, JPADotNames.ONE_TO_ONE ) == null
|
||||
&& JandexHelper.getSingleAnnotation( annotations, JPADotNames.ONE_TO_MANY ) == null
|
||||
&& JandexHelper.getSingleAnnotation( annotations, JPADotNames.MANY_TO_MANY ) == null ) {
|
||||
throw new MappingException(
|
||||
"@JoinTable annotation without an association",
|
||||
getContext().getOrigin()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return collectionTableAnnotation != null || joinTableAnnotation != null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
|
|||
/**
|
||||
* The nature of the attribute
|
||||
*/
|
||||
Nature attributeNature;
|
||||
private final Nature attributeNature;
|
||||
|
||||
/**
|
||||
* The access type for this property. At the moment this is either 'field' or 'property', but Hibernate
|
||||
|
@ -77,8 +77,6 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
|
|||
*/
|
||||
private List<Column> columnValues = new ArrayList<Column>();
|
||||
|
||||
private List<Column> joinColumnValues = new ArrayList<Column>();
|
||||
|
||||
/**
|
||||
* Is this property an id property (or part thereof).
|
||||
*/
|
||||
|
@ -154,10 +152,6 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
|
|||
return columnValues;
|
||||
}
|
||||
|
||||
public List<Column> getJoinColumnValues() {
|
||||
return joinColumnValues;
|
||||
}
|
||||
|
||||
public boolean isId() {
|
||||
return isId;
|
||||
}
|
||||
|
@ -250,15 +244,6 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
|
|||
columnValues.add( new Column( columnAnnotation ) );
|
||||
}
|
||||
|
||||
// single @JoinColumn
|
||||
AnnotationInstance joinColumnAnnotation = JandexHelper.getSingleAnnotation(
|
||||
annotations,
|
||||
JPADotNames.JOIN_COLUMN
|
||||
);
|
||||
if ( joinColumnAnnotation != null ) {
|
||||
joinColumnValues.add( new Column( joinColumnAnnotation ) );
|
||||
}
|
||||
|
||||
// @org.hibernate.annotations.Columns
|
||||
AnnotationInstance columnsAnnotation = JandexHelper.getSingleAnnotation(
|
||||
annotations,
|
||||
|
@ -278,20 +263,6 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
|
|||
columnValues.add( new Column( annotation ) );
|
||||
}
|
||||
}
|
||||
|
||||
// @JoinColumns
|
||||
AnnotationInstance joinColumnsAnnotation = JandexHelper.getSingleAnnotation(
|
||||
annotations,
|
||||
JPADotNames.JOIN_COLUMNS
|
||||
);
|
||||
if ( joinColumnsAnnotation != null ) {
|
||||
List<AnnotationInstance> columnsList = Arrays.asList(
|
||||
JandexHelper.getValue( joinColumnsAnnotation, "value", AnnotationInstance[].class )
|
||||
);
|
||||
for ( AnnotationInstance annotation : columnsList ) {
|
||||
joinColumnValues.add( new Column( annotation ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String checkCheckAnnotation() {
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.metamodel.internal.source.annotations.entity;
|
||||
|
||||
import java.util.List;
|
||||
import javax.persistence.CollectionTable;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinTable;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.metamodel.spi.source.MappingException;
|
||||
import org.hibernate.testing.junit4.BaseAnnotationBindingTestCase;
|
||||
import org.hibernate.testing.junit4.Resources;
|
||||
|
||||
/**
|
||||
* Tests for different types of @ElementCollection mappings.
|
||||
*
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
|
||||
public class ElementCollectionBindingTest extends BaseAnnotationBindingTestCase {
|
||||
@Entity
|
||||
class TestEntity {
|
||||
@Id
|
||||
private int id;
|
||||
|
||||
@ElementCollection
|
||||
@JoinTable
|
||||
private List<String> strings;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public List<String> getStrings() {
|
||||
return strings;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = MappingException.class)
|
||||
@Resources(annotatedClasses = { TestEntity.class })
|
||||
public void testElementCollectionWithJoinTableThrowsException() {
|
||||
getEntityBinding( TestEntity.class );
|
||||
}
|
||||
|
||||
@Entity
|
||||
class TestEntity2 {
|
||||
@Id
|
||||
private int id;
|
||||
|
||||
@ElementCollection
|
||||
@JoinTable
|
||||
@CollectionTable
|
||||
private List<String> strings;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public List<String> getStrings() {
|
||||
return strings;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = MappingException.class)
|
||||
@Resources(annotatedClasses = { TestEntity.class })
|
||||
public void testCollectionTableAndJoinTableThrowsException() {
|
||||
getEntityBinding( TestEntity.class );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -158,7 +158,7 @@ public class InheritanceBindingTest extends BaseAnnotationBindingTestCase {
|
|||
OtherSubclassOfSingleTableInheritance.class,
|
||||
SubclassOfSubclassOfSingleTableInheritance.class
|
||||
})
|
||||
public void testRootPolymporhism() {
|
||||
public void testRootPolymporphism() {
|
||||
EntityBinding rootEntityBinding = getEntityBinding( RootOfSingleTableInheritance.class );
|
||||
EntityBinding subclassEntityBinding = getEntityBinding( SubclassOfSingleTableInheritance.class );
|
||||
EntityBinding otherSubclassEntityBinding = getEntityBinding( OtherSubclassOfSingleTableInheritance.class );
|
||||
|
|
|
@ -104,7 +104,7 @@ public abstract class BaseAnnotationBindingTestCase extends BaseUnitTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
private void createBindings() {
|
||||
private void createBindings() throws Throwable {
|
||||
try {
|
||||
sources = new MetadataSources( new ServiceRegistryBuilder().buildServiceRegistry() );
|
||||
Resources resourcesAnnotation = origFrameworkMethod.getAnnotation( Resources.class );
|
||||
|
@ -127,6 +127,7 @@ public abstract class BaseAnnotationBindingTestCase extends BaseUnitTestCase {
|
|||
Class<?> expected = testAnnotation.expected();
|
||||
if ( t.getClass().equals( expected ) ) {
|
||||
expectedException = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue