Author: steve.ebersole(a)jboss.com
Date: 2010-07-08 19:41:23 -0400 (Thu, 08 Jul 2010)
New Revision: 19921
Added:
core/trunk/core/src/main/java/org/hibernate/AnnotationException.java
core/trunk/core/src/main/java/org/hibernate/annotations/
core/trunk/core/src/main/java/org/hibernate/annotations/AccessType.java
core/trunk/core/src/main/java/org/hibernate/annotations/Any.java
core/trunk/core/src/main/java/org/hibernate/annotations/AnyMetaDef.java
core/trunk/core/src/main/java/org/hibernate/annotations/AnyMetaDefs.java
core/trunk/core/src/main/java/org/hibernate/annotations/BatchSize.java
core/trunk/core/src/main/java/org/hibernate/annotations/Cache.java
core/trunk/core/src/main/java/org/hibernate/annotations/CacheConcurrencyStrategy.java
core/trunk/core/src/main/java/org/hibernate/annotations/CacheModeType.java
core/trunk/core/src/main/java/org/hibernate/annotations/Cascade.java
core/trunk/core/src/main/java/org/hibernate/annotations/CascadeType.java
core/trunk/core/src/main/java/org/hibernate/annotations/Check.java
core/trunk/core/src/main/java/org/hibernate/annotations/CollectionId.java
core/trunk/core/src/main/java/org/hibernate/annotations/CollectionOfElements.java
core/trunk/core/src/main/java/org/hibernate/annotations/Columns.java
core/trunk/core/src/main/java/org/hibernate/annotations/DiscriminatorFormula.java
core/trunk/core/src/main/java/org/hibernate/annotations/Entity.java
core/trunk/core/src/main/java/org/hibernate/annotations/Fetch.java
core/trunk/core/src/main/java/org/hibernate/annotations/FetchMode.java
core/trunk/core/src/main/java/org/hibernate/annotations/FetchProfile.java
core/trunk/core/src/main/java/org/hibernate/annotations/FetchProfiles.java
core/trunk/core/src/main/java/org/hibernate/annotations/Filter.java
core/trunk/core/src/main/java/org/hibernate/annotations/FilterDef.java
core/trunk/core/src/main/java/org/hibernate/annotations/FilterDefs.java
core/trunk/core/src/main/java/org/hibernate/annotations/FilterJoinTable.java
core/trunk/core/src/main/java/org/hibernate/annotations/FilterJoinTables.java
core/trunk/core/src/main/java/org/hibernate/annotations/Filters.java
core/trunk/core/src/main/java/org/hibernate/annotations/FlushModeType.java
core/trunk/core/src/main/java/org/hibernate/annotations/ForceDiscriminator.java
core/trunk/core/src/main/java/org/hibernate/annotations/ForeignKey.java
core/trunk/core/src/main/java/org/hibernate/annotations/Formula.java
core/trunk/core/src/main/java/org/hibernate/annotations/Generated.java
core/trunk/core/src/main/java/org/hibernate/annotations/GenerationTime.java
core/trunk/core/src/main/java/org/hibernate/annotations/GenericGenerator.java
core/trunk/core/src/main/java/org/hibernate/annotations/GenericGenerators.java
core/trunk/core/src/main/java/org/hibernate/annotations/Immutable.java
core/trunk/core/src/main/java/org/hibernate/annotations/Index.java
core/trunk/core/src/main/java/org/hibernate/annotations/IndexColumn.java
core/trunk/core/src/main/java/org/hibernate/annotations/JoinColumnOrFormula.java
core/trunk/core/src/main/java/org/hibernate/annotations/JoinColumnsOrFormulas.java
core/trunk/core/src/main/java/org/hibernate/annotations/JoinFormula.java
core/trunk/core/src/main/java/org/hibernate/annotations/LazyCollection.java
core/trunk/core/src/main/java/org/hibernate/annotations/LazyCollectionOption.java
core/trunk/core/src/main/java/org/hibernate/annotations/LazyToOne.java
core/trunk/core/src/main/java/org/hibernate/annotations/LazyToOneOption.java
core/trunk/core/src/main/java/org/hibernate/annotations/Loader.java
core/trunk/core/src/main/java/org/hibernate/annotations/ManyToAny.java
core/trunk/core/src/main/java/org/hibernate/annotations/MapKey.java
core/trunk/core/src/main/java/org/hibernate/annotations/MapKeyManyToMany.java
core/trunk/core/src/main/java/org/hibernate/annotations/MetaValue.java
core/trunk/core/src/main/java/org/hibernate/annotations/NamedNativeQueries.java
core/trunk/core/src/main/java/org/hibernate/annotations/NamedNativeQuery.java
core/trunk/core/src/main/java/org/hibernate/annotations/NamedQueries.java
core/trunk/core/src/main/java/org/hibernate/annotations/NamedQuery.java
core/trunk/core/src/main/java/org/hibernate/annotations/NaturalId.java
core/trunk/core/src/main/java/org/hibernate/annotations/NotFound.java
core/trunk/core/src/main/java/org/hibernate/annotations/NotFoundAction.java
core/trunk/core/src/main/java/org/hibernate/annotations/OnDelete.java
core/trunk/core/src/main/java/org/hibernate/annotations/OnDeleteAction.java
core/trunk/core/src/main/java/org/hibernate/annotations/OptimisticLock.java
core/trunk/core/src/main/java/org/hibernate/annotations/OptimisticLockType.java
core/trunk/core/src/main/java/org/hibernate/annotations/OrderBy.java
core/trunk/core/src/main/java/org/hibernate/annotations/ParamDef.java
core/trunk/core/src/main/java/org/hibernate/annotations/Parameter.java
core/trunk/core/src/main/java/org/hibernate/annotations/Parent.java
core/trunk/core/src/main/java/org/hibernate/annotations/Persister.java
core/trunk/core/src/main/java/org/hibernate/annotations/PolymorphismType.java
core/trunk/core/src/main/java/org/hibernate/annotations/Proxy.java
core/trunk/core/src/main/java/org/hibernate/annotations/ResultCheckStyle.java
core/trunk/core/src/main/java/org/hibernate/annotations/SQLDelete.java
core/trunk/core/src/main/java/org/hibernate/annotations/SQLDeleteAll.java
core/trunk/core/src/main/java/org/hibernate/annotations/SQLInsert.java
core/trunk/core/src/main/java/org/hibernate/annotations/SQLUpdate.java
core/trunk/core/src/main/java/org/hibernate/annotations/Sort.java
core/trunk/core/src/main/java/org/hibernate/annotations/SortType.java
core/trunk/core/src/main/java/org/hibernate/annotations/Subselect.java
core/trunk/core/src/main/java/org/hibernate/annotations/Synchronize.java
core/trunk/core/src/main/java/org/hibernate/annotations/Table.java
core/trunk/core/src/main/java/org/hibernate/annotations/Tables.java
core/trunk/core/src/main/java/org/hibernate/annotations/Target.java
core/trunk/core/src/main/java/org/hibernate/annotations/Tuplizer.java
core/trunk/core/src/main/java/org/hibernate/annotations/Tuplizers.java
core/trunk/core/src/main/java/org/hibernate/annotations/Type.java
core/trunk/core/src/main/java/org/hibernate/annotations/TypeDef.java
core/trunk/core/src/main/java/org/hibernate/annotations/TypeDefs.java
core/trunk/core/src/main/java/org/hibernate/annotations/Where.java
core/trunk/core/src/main/java/org/hibernate/annotations/WhereJoinTable.java
core/trunk/core/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java
core/trunk/core/src/main/java/org/hibernate/cfg/AccessType.java
core/trunk/core/src/main/java/org/hibernate/cfg/AnnotatedClassType.java
core/trunk/core/src/main/java/org/hibernate/cfg/AnnotationBinder.java
core/trunk/core/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java
core/trunk/core/src/main/java/org/hibernate/cfg/BinderHelper.java
core/trunk/core/src/main/java/org/hibernate/cfg/ClassPropertyHolder.java
core/trunk/core/src/main/java/org/hibernate/cfg/CollectionPropertyHolder.java
core/trunk/core/src/main/java/org/hibernate/cfg/ColumnsBuilder.java
core/trunk/core/src/main/java/org/hibernate/cfg/ComponentPropertyHolder.java
core/trunk/core/src/main/java/org/hibernate/cfg/ConfigurationArtefactType.java
core/trunk/core/src/main/java/org/hibernate/cfg/CopyIdentifierComponentSecondPass.java
core/trunk/core/src/main/java/org/hibernate/cfg/CreateKeySecondPass.java
core/trunk/core/src/main/java/org/hibernate/cfg/DefaultComponentSafeNamingStrategy.java
core/trunk/core/src/main/java/org/hibernate/cfg/EJB3DTDEntityResolver.java
core/trunk/core/src/main/java/org/hibernate/cfg/EJB3NamingStrategy.java
core/trunk/core/src/main/java/org/hibernate/cfg/Ejb3Column.java
core/trunk/core/src/main/java/org/hibernate/cfg/Ejb3DiscriminatorColumn.java
core/trunk/core/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java
core/trunk/core/src/main/java/org/hibernate/cfg/ExtendedMappings.java
core/trunk/core/src/main/java/org/hibernate/cfg/FkSecondPass.java
core/trunk/core/src/main/java/org/hibernate/cfg/IndexColumn.java
core/trunk/core/src/main/java/org/hibernate/cfg/IndexOrUniqueKeySecondPass.java
core/trunk/core/src/main/java/org/hibernate/cfg/InheritanceState.java
core/trunk/core/src/main/java/org/hibernate/cfg/JoinedSubclassFkSecondPass.java
core/trunk/core/src/main/java/org/hibernate/cfg/NotYetImplementedException.java
core/trunk/core/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java
core/trunk/core/src/main/java/org/hibernate/cfg/PkDrivenByDefaultMapsIdSecondPass.java
core/trunk/core/src/main/java/org/hibernate/cfg/PropertyContainer.java
core/trunk/core/src/main/java/org/hibernate/cfg/PropertyData.java
core/trunk/core/src/main/java/org/hibernate/cfg/PropertyHolder.java
core/trunk/core/src/main/java/org/hibernate/cfg/PropertyHolderBuilder.java
core/trunk/core/src/main/java/org/hibernate/cfg/PropertyInferredData.java
core/trunk/core/src/main/java/org/hibernate/cfg/PropertyPreloadedData.java
core/trunk/core/src/main/java/org/hibernate/cfg/RecoverableException.java
core/trunk/core/src/main/java/org/hibernate/cfg/SecondaryTableSecondPass.java
core/trunk/core/src/main/java/org/hibernate/cfg/SetSimpleValueTypeSecondPass.java
core/trunk/core/src/main/java/org/hibernate/cfg/ToOneBinder.java
core/trunk/core/src/main/java/org/hibernate/cfg/ToOneFkSecondPass.java
core/trunk/core/src/main/java/org/hibernate/cfg/UniqueConstraintHolder.java
core/trunk/core/src/main/java/org/hibernate/cfg/VerifyFetchProfileReferenceSecondPass.java
core/trunk/core/src/main/java/org/hibernate/cfg/WrappedInferredData.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/ArrayBinder.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/BagBinder.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/CustomizableColumns.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/IdBagBinder.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/ListBinder.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/MapBinder.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/MapKeyColumnDelegator.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/MapKeyJoinColumnDelegator.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/Nullability.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/PrimitiveArrayBinder.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/QueryBinder.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/ResultsetMappingSecondPass.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/SetBinder.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/SimpleValueBinder.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/TableBinder.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/Version.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/reflection/
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/reflection/JPAMetadataProvider.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/reflection/JPAOverridenAnnotationReader.java
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/reflection/XMLContext.java
core/trunk/core/src/main/java/org/hibernate/cfg/beanvalidation/
core/trunk/core/src/main/java/org/hibernate/cfg/beanvalidation/BeanValidationActivator.java
core/trunk/core/src/main/java/org/hibernate/cfg/beanvalidation/BeanValidationEventListener.java
core/trunk/core/src/main/java/org/hibernate/cfg/beanvalidation/GroupsPerOperation.java
core/trunk/core/src/main/java/org/hibernate/cfg/beanvalidation/HibernateTraversableResolver.java
core/trunk/core/src/main/java/org/hibernate/cfg/beanvalidation/TypeSafeActivator.java
core/trunk/core/src/main/java/org/hibernate/cfg/search/
core/trunk/core/src/main/java/org/hibernate/cfg/search/HibernateSearchEventListenerRegister.java
core/trunk/core/src/main/java/org/hibernate/mapping/IdGenerator.java
core/trunk/core/src/main/java/org/hibernate/mapping/SyntheticProperty.java
core/trunk/core/src/main/java/org/hibernate/type/AbstractLobType.java
core/trunk/core/src/main/java/org/hibernate/type/ByteArrayBlobType.java
core/trunk/core/src/main/java/org/hibernate/type/CharacterArrayClobType.java
core/trunk/core/src/main/java/org/hibernate/type/EnumType.java
core/trunk/core/src/main/java/org/hibernate/type/PrimitiveByteArrayBlobType.java
core/trunk/core/src/main/java/org/hibernate/type/PrimitiveCharacterArrayClobType.java
core/trunk/core/src/main/java/org/hibernate/type/SerializableToBlobType.java
core/trunk/core/src/main/java/org/hibernate/type/StringClobType.java
core/trunk/core/src/main/java/org/hibernate/type/WrappedMaterializedBlobType.java
core/trunk/core/src/main/resources/org/hibernate/ejb/
core/trunk/core/src/main/resources/org/hibernate/ejb/orm_1_0.xsd
core/trunk/core/src/main/resources/org/hibernate/ejb/orm_2_0.xsd
Removed:
core/trunk/annotations/src/main/java/
core/trunk/annotations/src/main/resources/org/hibernate/ejb/
Modified:
core/trunk/annotations/pom.xml
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/cid/SomeEntityId.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/collectionelement/Boy.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/collectionelement/LocalizedString.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/embedded/WealthyPerson.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/idclassgeneratedvalue/Simple.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/idclassgeneratedvalue/Simple2.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/immutable/ImmutableTest.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/manytomany/Cat.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/manytomany/GroupWithSet.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/manytoone/Frame.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/onetoone/OneToOneErrorTest.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/onetoone/hhh4851/Hardware.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/override/PropertyRecord.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/query/Chaos.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/target/Brand.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/target/LuggageImpl.java
core/trunk/core/pom.xml
core/trunk/distribution/pom.xml
core/trunk/entitymanager/pom.xml
core/trunk/envers/pom.xml
Log:
HHH-5367 - Move annotations module sources into core module
Modified: core/trunk/annotations/pom.xml
===================================================================
--- core/trunk/annotations/pom.xml 2010-07-08 17:32:44 UTC (rev 19920)
+++ core/trunk/annotations/pom.xml 2010-07-08 23:41:23 UTC (rev 19921)
@@ -105,6 +105,7 @@
<groupId>org.jboss.maven.plugins</groupId>
<artifactId>maven-test-ext-plugin</artifactId>
</plugin>
+<!--
<plugin>
<groupId>org.jboss.maven.plugins</groupId>
<artifactId>maven-injection-plugin</artifactId>
@@ -122,6 +123,7 @@
</bytecodeInjections>
</configuration>
</plugin>
+-->
<plugin>
<groupId>org.twdata.maven</groupId>
<artifactId>maven-cli-plugin</artifactId>
Modified:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/cid/SomeEntityId.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/cid/SomeEntityId.java 2010-07-08
17:32:44 UTC (rev 19920)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/cid/SomeEntityId.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -3,8 +3,6 @@
import java.io.Serializable;
import javax.persistence.Embeddable;
-import org.hibernate.annotations.*;
-
/**
* @author bartek
*/
Modified:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/collectionelement/Boy.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/collectionelement/Boy.java 2010-07-08
17:32:44 UTC (rev 19920)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/collectionelement/Boy.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -21,7 +21,6 @@
import javax.persistence.Table;
import org.hibernate.annotations.CollectionOfElements;
-import org.hibernate.test.annotations.collectionelement.FavoriteFood;
/**
* @author Emmanuel Bernard
Modified:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/collectionelement/LocalizedString.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/collectionelement/LocalizedString.java 2010-07-08
17:32:44 UTC (rev 19920)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/collectionelement/LocalizedString.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -5,7 +5,6 @@
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
-import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Embeddable;
import javax.persistence.MapKeyColumn;
@@ -13,7 +12,6 @@
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.Filter;
-import org.hibernate.annotations.MapKey;
/**
* @author Emmanuel Bernard
Modified:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/embedded/WealthyPerson.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/embedded/WealthyPerson.java 2010-07-08
17:32:44 UTC (rev 19920)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/embedded/WealthyPerson.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -1,16 +1,8 @@
package org.hibernate.test.annotations.embedded;
-import javax.persistence.AttributeOverride;
-import javax.persistence.AttributeOverrides;
import javax.persistence.CollectionTable;
-import javax.persistence.Column;
import javax.persistence.ElementCollection;
-import javax.persistence.Embedded;
import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
Modified:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/idclassgeneratedvalue/Simple.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/idclassgeneratedvalue/Simple.java 2010-07-08
17:32:44 UTC (rev 19920)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/idclassgeneratedvalue/Simple.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -24,15 +24,10 @@
package org.hibernate.test.annotations.idclassgeneratedvalue;
import java.io.Serializable;
-import javax.persistence.Column;
import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.IdClass;
-import javax.persistence.Table;
-import org.hibernate.annotations.GenericGenerator;
-
/**
* A Simple entity class.
*
Modified:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/idclassgeneratedvalue/Simple2.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/idclassgeneratedvalue/Simple2.java 2010-07-08
17:32:44 UTC (rev 19920)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/idclassgeneratedvalue/Simple2.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -28,7 +28,6 @@
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.IdClass;
-import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
Modified:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/immutable/ImmutableTest.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/immutable/ImmutableTest.java 2010-07-08
17:32:44 UTC (rev 19920)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/immutable/ImmutableTest.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -1,8 +1,6 @@
//$Id$
package org.hibernate.test.annotations.immutable;
-import java.io.PrintWriter;
-import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
@@ -11,12 +9,8 @@
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
-import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.test.annotations.TestCase;
-import org.hibernate.test.annotations.fkcircularity.A;
-import org.hibernate.test.annotations.fkcircularity.B;
-import org.hibernate.test.annotations.fkcircularity.C;
-import org.hibernate.test.annotations.fkcircularity.D;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Modified:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/manytomany/Cat.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/manytomany/Cat.java 2010-07-08
17:32:44 UTC (rev 19920)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/manytomany/Cat.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -7,10 +7,7 @@
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.JoinTable;
-import javax.persistence.JoinColumn;
-import org.hibernate.annotations.Index;
-
/**
* @author Emmanuel Bernard
*/
Modified:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/manytomany/GroupWithSet.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/manytomany/GroupWithSet.java 2010-07-08
17:32:44 UTC (rev 19920)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/manytomany/GroupWithSet.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -1,18 +1,14 @@
//$Id$
package org.hibernate.test.annotations.manytomany;
-import java.util.Collection;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
-import javax.persistence.UniqueConstraint;
import org.hibernate.annotations.Where;
import org.hibernate.annotations.FilterDef;
Modified:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/manytoone/Frame.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/manytoone/Frame.java 2010-07-08
17:32:44 UTC (rev 19920)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/manytoone/Frame.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -3,7 +3,6 @@
import java.util.Set;
import java.io.Serializable;
-import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
Modified:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/onetoone/OneToOneErrorTest.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/onetoone/OneToOneErrorTest.java 2010-07-08
17:32:44 UTC (rev 19920)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/onetoone/OneToOneErrorTest.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -3,7 +3,6 @@
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Environment;
-import org.hibernate.test.annotations.IncorrectEntity;
import org.hibernate.SessionFactory;
import org.hibernate.AnnotationException;
Modified:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/onetoone/hhh4851/Hardware.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/onetoone/hhh4851/Hardware.java 2010-07-08
17:32:44 UTC (rev 19920)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/onetoone/hhh4851/Hardware.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -1,7 +1,5 @@
package org.hibernate.test.annotations.onetoone.hhh4851;
-import java.util.ArrayList;
-import java.util.List;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
@@ -10,14 +8,9 @@
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
-import javax.persistence.JoinTable;
-import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
-import org.hibernate.annotations.Cascade;
-import org.hibernate.annotations.CascadeType;
-
@Entity
@Table
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
Modified:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/override/PropertyRecord.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/override/PropertyRecord.java 2010-07-08
17:32:44 UTC (rev 19920)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/override/PropertyRecord.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -11,7 +11,6 @@
import javax.persistence.Id;
import javax.persistence.CollectionTable;
-import org.hibernate.annotations.MapKey;
import org.hibernate.annotations.CollectionOfElements;
/**
Modified:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/query/Chaos.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/query/Chaos.java 2010-07-08
17:32:44 UTC (rev 19920)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/query/Chaos.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -6,7 +6,6 @@
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
-import javax.persistence.NamedQuery;
import javax.persistence.NamedNativeQuery;
import javax.persistence.OneToMany;
import javax.persistence.JoinColumn;
Modified:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/target/Brand.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/target/Brand.java 2010-07-08
17:32:44 UTC (rev 19920)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/target/Brand.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -9,9 +9,7 @@
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.MapKeyClass;
-import javax.persistence.JoinColumn;
-import org.hibernate.annotations.MapKey;
import org.hibernate.annotations.MapKeyManyToMany;
/**
Modified:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/target/LuggageImpl.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/target/LuggageImpl.java 2010-07-08
17:32:44 UTC (rev 19920)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/target/LuggageImpl.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -4,7 +4,6 @@
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
-import javax.persistence.ManyToOne;
import javax.persistence.Embedded;
import org.hibernate.annotations.Target;
Modified: core/trunk/core/pom.xml
===================================================================
--- core/trunk/core/pom.xml 2010-07-08 17:32:44 UTC (rev 19920)
+++ core/trunk/core/pom.xml 2010-07-08 23:41:23 UTC (rev 19921)
@@ -30,6 +30,19 @@
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-commons-annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.hibernate.javax.persistence</groupId>
+ <artifactId>hibernate-jpa-2.0-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.validation</groupId>
+ <artifactId>validation-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
<!-- optional deps for bytecode providers until those are finally properly
scoped -->
<dependency>
Copied: core/trunk/core/src/main/java/org/hibernate/AnnotationException.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/AnnotationException.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/AnnotationException.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/AnnotationException.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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;
+
+/**
+ * Annotation related exception.
+ * The EJB3 EG will probably set a generic exception.
+ * I'll then use this one.
+ *
+ * @author Emmanuel Bernard
+ */
+public class AnnotationException extends MappingException {
+
+ public AnnotationException(String msg, Throwable root) {
+ super( msg, root );
+ }
+
+ public AnnotationException(Throwable root) {
+ super( root );
+ }
+
+ public AnnotationException(String s) {
+ super( s );
+ }
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/AnnotationException.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/AccessType.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/AccessType.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/AccessType.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/AccessType.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,45 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Property Access type
+ *
+ * Prefer the standard {@link javax.persistence.Access} annotation
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({ TYPE, METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface AccessType {
+ String value();
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/AccessType.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Any.java (from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/Any.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Any.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Any.java 2010-07-08 23:41:23
UTC (rev 19921)
@@ -0,0 +1,67 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import javax.persistence.Column;
+import javax.persistence.FetchType;
+import static javax.persistence.FetchType.EAGER;
+
+/**
+ * Define a ToOne association pointing to several entity types.
+ * Matching the according entity type is doe through a metadata discriminator column
+ * This kind of mapping should be only marginal.
+ *
+ * @author Emmanuel Bernard
+ */
+(a)java.lang.annotation.Target({METHOD, FIELD})
+@Retention(RUNTIME)
+public @interface Any {
+ /**
+ * Metadata definition used.
+ * If defined, should point to a @AnyMetaDef name
+ * If not defined, the local (ie in the same field or property) @AnyMetaDef is used
+ */
+ String metaDef() default "";
+
+ /**
+ * Metadata discriminator column description, This column will hold the meta value
corresponding to the
+ * targeted entity.
+ */
+ Column metaColumn();
+ /**
+ * Defines whether the value of the field or property should be lazily loaded or must
be
+ * eagerly fetched. The EAGER strategy is a requirement on the persistence provider
runtime
+ * that the value must be eagerly fetched. The LAZY strategy is applied when bytecode
+ * enhancement is used. If not specified, defaults to EAGER.
+ */
+ FetchType fetch() default FetchType.EAGER;
+ /**
+ * Whether the association is optional. If set to false then a non-null relationship
must always exist.
+ */
+ boolean optional() default true;
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/Any.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/AnyMetaDef.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/AnyMetaDef.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/AnyMetaDef.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/AnyMetaDef.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,62 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Defines @Any and @manyToAny metadata
+ *
+ * @author Emmanuel Bernard
+ */
+(a)java.lang.annotation.Target( { PACKAGE, TYPE, METHOD, FIELD } )
+@Retention( RUNTIME )
+public @interface AnyMetaDef {
+ /**
+ * If defined, assign a global meta definition name to be used in an @Any or @ManyToAny
annotation
+ * If not defined, the metadata applies to the current property or field
+ */
+ String name() default "";
+
+ /**
+ * meta discriminator Hibernate type
+ */
+ String metaType();
+
+ /**
+ * Hibernate type of the id column
+ * @return
+ */
+ String idType();
+
+ /**
+ * Matching discriminator values with their respective entity
+ */
+ MetaValue[] metaValues();
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/AnyMetaDef.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/AnyMetaDefs.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/AnyMetaDefs.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/AnyMetaDefs.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/AnyMetaDefs.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,41 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Defines @Any and @ManyToAny set of metadata.
+ * Can be defined at the entity level or the package level
+ *
+ * @author Emmanuel Bernard
+ */
+(a)java.lang.annotation.Target( { PACKAGE, TYPE } )
+@Retention( RUNTIME )
+public @interface AnyMetaDefs {
+ AnyMetaDef[] value();
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/AnyMetaDefs.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/BatchSize.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/BatchSize.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/BatchSize.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/BatchSize.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,41 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.*;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Batch size for SQL loading
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({TYPE, METHOD, FIELD})
+@Retention(RUNTIME)
+public @interface BatchSize {
+ /** Strictly positive integer */
+ int size();
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/BatchSize.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Cache.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Cache.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Cache.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Cache.java 2010-07-08 23:41:23
UTC (rev 19921)
@@ -0,0 +1,48 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.*;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Add caching strategy to a root entity or a collection
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({TYPE, METHOD, FIELD})
+@Retention(RUNTIME)
+public @interface Cache {
+ /** concurrency strategy chosen */
+ CacheConcurrencyStrategy usage();
+ /** cache region name */
+ String region() default "";
+ /**
+ * whether or not lazy-properties are included in the second level cache
+ * default all, other value: non-lazy
+ */
+ String include() default "all";
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/Cache.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied:
core/trunk/core/src/main/java/org/hibernate/annotations/CacheConcurrencyStrategy.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/CacheConcurrencyStrategy.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/CacheConcurrencyStrategy.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/annotations/CacheConcurrencyStrategy.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,89 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import org.hibernate.cache.access.AccessType;
+
+/**
+ * Cache concurrency strategy
+ *
+ * @author Emmanuel Bernard
+ */
+public enum CacheConcurrencyStrategy {
+ NONE( null ),
+ READ_ONLY( AccessType.READ_ONLY ),
+ NONSTRICT_READ_WRITE( AccessType.NONSTRICT_READ_WRITE ),
+ READ_WRITE( AccessType.READ_WRITE ),
+ TRANSACTIONAL( AccessType.TRANSACTIONAL );
+
+ private final AccessType accessType;
+
+ private CacheConcurrencyStrategy(AccessType accessType) {
+ this.accessType = accessType;
+ }
+
+ public static CacheConcurrencyStrategy fromAccessType(AccessType accessType) {
+ final String name = accessType == null ? null : accessType.getName();
+ if ( AccessType.READ_ONLY.getName().equals( name ) ) {
+ return READ_ONLY;
+ }
+ else if ( AccessType.READ_WRITE.getName().equals( name ) ) {
+ return READ_WRITE;
+ }
+ else if ( AccessType.NONSTRICT_READ_WRITE.getName().equals( name ) ) {
+ return NONSTRICT_READ_WRITE;
+ }
+ else if ( AccessType.TRANSACTIONAL.getName().equals( name ) ) {
+ return TRANSACTIONAL;
+ }
+ else {
+ return NONE;
+ }
+ }
+
+ public static CacheConcurrencyStrategy parse(String name) {
+ if ( READ_ONLY.accessType.getName().equalsIgnoreCase( name ) ) {
+ return READ_ONLY;
+ }
+ else if ( READ_WRITE.accessType.getName().equalsIgnoreCase( name ) ) {
+ return READ_WRITE;
+ }
+ else if ( NONSTRICT_READ_WRITE.accessType.getName().equalsIgnoreCase( name ) ) {
+ return NONSTRICT_READ_WRITE;
+ }
+ else if ( TRANSACTIONAL.accessType.getName().equalsIgnoreCase( name ) ) {
+ return TRANSACTIONAL;
+ }
+ else if ( "none".equalsIgnoreCase( name ) ) {
+ return NONE;
+ }
+ else {
+ return null;
+ }
+ }
+
+ public AccessType toAccessType() {
+ return accessType;
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/CacheConcurrencyStrategy.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/CacheModeType.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/CacheModeType.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/CacheModeType.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/CacheModeType.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,40 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+/**
+ * Enumeration for the different interaction modes between the session and
+ * the Level 2 Cache.
+ *
+ * @author Emmanuel Bernard
+ * @author Carlos Gonz�lez-Cadenas
+ */
+
+public enum CacheModeType {
+ GET,
+ IGNORE,
+ NORMAL,
+ PUT,
+ REFRESH
+}
\ No newline at end of file
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/CacheModeType.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Cascade.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Cascade.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Cascade.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Cascade.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,39 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Apply a cascade strategy on an association
+ */
+@Target({METHOD, FIELD})
+@Retention(RUNTIME)
+public @interface Cascade {
+ CascadeType[] value();
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/Cascade.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/CascadeType.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/CascadeType.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/CascadeType.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/CascadeType.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+/**
+ * Cascade types (can override default EJB3 cascades
+ */
+public enum CascadeType {
+ ALL,
+ PERSIST,
+ MERGE,
+ REMOVE,
+ REFRESH,
+ DELETE,
+ SAVE_UPDATE,
+ REPLICATE,
+ /** @deprecated use @OneToOne(orphanRemoval=true) or @OneToMany(orphanRemoval=true) */
+ @Deprecated
+ DELETE_ORPHAN,
+ LOCK,
+ /** @deprecated use javax.persistence.CascadeType.DETACH */
+ @Deprecated
+ EVICT,
+ DETACH
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/CascadeType.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Check.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Check.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Check.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Check.java 2010-07-08 23:41:23
UTC (rev 19921)
@@ -0,0 +1,41 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.*;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Arbitrary SQL check constraints which can be defined at the class,
+ * property or collection level
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({TYPE, METHOD, FIELD})
+@Retention(RUNTIME)
+public @interface Check {
+ String constraints();
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/Check.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/CollectionId.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/CollectionId.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/CollectionId.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/CollectionId.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,48 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.FIELD;
+import javax.persistence.Column;
+
+/**
+ * Describe an identifier column for a bag (ie an idbag)
+ * EXPERIMENTAL: the structure of this annotation might slightly change (generator() mix
strategy and generator
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({METHOD, FIELD})
+@Retention(RUNTIME)
+public @interface CollectionId {
+ /** Collection id column(s) */
+ Column[] columns();
+ /** id type, type.type() must be set */
+ Type type();
+ /** generator name: 'identity' or a defined generator name */
+ String generator();
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/CollectionId.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/CollectionOfElements.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/CollectionOfElements.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/CollectionOfElements.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/annotations/CollectionOfElements.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,52 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+import javax.persistence.FetchType;
+import static javax.persistence.FetchType.LAZY;
+
+/**
+ * Annotation used to mark a collection as a collection of elements or
+ * a collection of embedded objects
+ *
+ * @deprecated use @ElementCollection
+ * @author Emmanuel Bernard
+ */
+@Target({METHOD, FIELD})
+@Retention(RUNTIME)
+@Deprecated
+public @interface CollectionOfElements {
+ /**
+ * Represent the element class in the collection
+ * Only useful if the collection does not use generics
+ */
+ Class targetElement() default void.class;
+
+ FetchType fetch() default FetchType.LAZY;
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/CollectionOfElements.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Columns.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Columns.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Columns.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Columns.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,42 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+import javax.persistence.Column;
+
+/**
+ * Support an array of columns. Useful for component user types mappings
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({METHOD, FIELD})
+@Retention(RUNTIME)
+public @interface Columns {
+ Column[] columns();
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/Columns.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/DiscriminatorFormula.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/DiscriminatorFormula.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/DiscriminatorFormula.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/annotations/DiscriminatorFormula.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,42 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Discriminator formula
+ * To be placed at the root entity.
+ *
+ * @author Emmanuel Bernard
+ * @see Formula
+ */
+@Target({TYPE})
+@Retention(RUNTIME)
+public @interface DiscriminatorFormula {
+ String value();
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/DiscriminatorFormula.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Entity.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Entity.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Entity.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Entity.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,57 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Extends {@link javax.persistence.Entity} with Hibernate features
+ *
+ * @author Emmanuel Bernard
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+public @interface Entity {
+ /**
+ * Is this entity mutable (read only) or not
+ *
+ * @deprecated use {@link org.hibernate.annotations.Immutable}
+ */
+ boolean mutable() default true;
+ /** Needed column only in SQL on insert */
+ boolean dynamicInsert() default false;
+ /** Needed column only in SQL on update */
+ boolean dynamicUpdate() default false;
+ /** Do a select to retrieve the entity before any potential update */
+ boolean selectBeforeUpdate() default false;
+ /** polymorphism strategy for this entity */
+ PolymorphismType polymorphism() default PolymorphismType.IMPLICIT;
+ /** persister of this entity, default is hibernate internal one */
+ String persister() default "";
+ /** optimistic locking strategy */
+ OptimisticLockType optimisticLock() default OptimisticLockType.VERSION;
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/Entity.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Fetch.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Fetch.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Fetch.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Fetch.java 2010-07-08 23:41:23
UTC (rev 19921)
@@ -0,0 +1,40 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Define the fetching strategy used for the given association
+ *
+ * @author Emmanuel Bernard
+ */
+(a)Target({ElementType.METHOD, ElementType.FIELD})
+(a)Retention(RetentionPolicy.RUNTIME)
+public @interface Fetch {
+ FetchMode value();
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/Fetch.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/FetchMode.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/FetchMode.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/FetchMode.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/FetchMode.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,44 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+/**
+ * Fetch options on associations
+ *
+ * @author Emmanuel Bernard
+ */
+public enum FetchMode {
+ /**
+ * use a select for each individual entity, collection, or join load
+ */
+ SELECT,
+ /**
+ * use an outer join to load the related entities, collections or joins
+ */
+ JOIN,
+ /**
+ * use a subselect query to load the additional collections
+ */
+ SUBSELECT
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/FetchMode.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/FetchProfile.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/FetchProfile.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/FetchProfile.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/FetchProfile.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,55 @@
+// $Id$
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Define the fetching strategy profile.
+ *
+ * @author Hardy Ferentschik
+ */
+@Target({ TYPE, PACKAGE })
+@Retention(RUNTIME)
+public @interface FetchProfile {
+ String name();
+
+ FetchOverride[] fetchOverrides();
+
+ @Target({ TYPE, PACKAGE })
+ @Retention(RUNTIME)
+ @interface FetchOverride {
+ Class<?> entity();
+
+ String association();
+
+ FetchMode mode();
+ }
+}
\ No newline at end of file
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/FetchProfile.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/FetchProfiles.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/FetchProfiles.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/FetchProfiles.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/FetchProfiles.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,41 @@
+// $Id$
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Target({ TYPE, PACKAGE })
+@Retention(RUNTIME)
+public @interface FetchProfiles {
+ public abstract FetchProfile[] value();
+}
\ No newline at end of file
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/FetchProfiles.java
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Filter.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Filter.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Filter.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Filter.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,44 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.*;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Add filters to an entity or a target entity of a collection
+ *
+ * @author Emmanuel Bernard
+ * @author Matthew Inger
+ * @author Magnus Sandberg
+ */
+@Target({TYPE, METHOD, FIELD})
+@Retention(RUNTIME)
+public @interface Filter {
+ String name();
+
+ String condition() default "";
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/Filter.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/FilterDef.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/FilterDef.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/FilterDef.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/FilterDef.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Filter definition
+ *
+ * @author Matthew Inger
+ * @author Emmanuel Bernard
+ */
+@Target({TYPE, PACKAGE})
+@Retention(RUNTIME)
+public @interface FilterDef {
+ String name();
+
+ String defaultCondition() default "";
+
+ ParamDef[] parameters() default {};
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/FilterDef.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/FilterDefs.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/FilterDefs.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/FilterDefs.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/FilterDefs.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,42 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Array of filter definitions
+ *
+ * @author Matthew Inger
+ * @author Emmanuel Bernard
+ */
+@Target({PACKAGE, TYPE})
+@Retention(RUNTIME)
+public @interface FilterDefs {
+ FilterDef[] value();
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/FilterDefs.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/FilterJoinTable.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/FilterJoinTable.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/FilterJoinTable.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/annotations/FilterJoinTable.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,44 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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
+ */
+
+//$Id$
+package org.hibernate.annotations;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Add filters to a join table collection
+ *
+ * @author Emmanuel Bernard
+ */
+(a)Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
+(a)Retention(RetentionPolicy.RUNTIME)
+public @interface FilterJoinTable {
+ String name();
+
+ String condition() default "";
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/FilterJoinTable.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/FilterJoinTables.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/FilterJoinTables.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/FilterJoinTables.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/annotations/FilterJoinTables.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,40 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Add multiple @FilterJoinTable to a collection
+ *
+ * @author Emmanuel Bernard
+ */
+(a)Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
+(a)Retention(RetentionPolicy.RUNTIME)
+public @interface FilterJoinTables {
+ FilterJoinTable[] value();
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/FilterJoinTables.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Filters.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Filters.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Filters.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Filters.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,42 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.*;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Add multiple @Filters
+ *
+ * @author Emmanuel Bernard
+ * @author Matthew Inger
+ * @author Magnus Sandberg
+ */
+@Target({TYPE, METHOD, FIELD})
+@Retention(RUNTIME)
+public @interface Filters {
+ Filter[] value();
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/Filters.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/FlushModeType.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/FlushModeType.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/FlushModeType.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/FlushModeType.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,59 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+/**
+ * Enumeration extending javax.persistence flush modes.
+ *
+ * @author Carlos Gonz�lez-Cadenas
+ */
+
+public enum FlushModeType {
+ /**
+ * see {@link org.hibernate.FlushMode#ALWAYS}
+ */
+ ALWAYS,
+ /**
+ * see {@link org.hibernate.FlushMode#AUTO}
+ */
+ AUTO,
+ /**
+ * see {@link org.hibernate.FlushMode#COMMIT}
+ */
+ COMMIT,
+ /**
+ * see {@link org.hibernate.FlushMode#NEVER}
+ * @deprecated use MANUAL, will be removed in a subsequent release
+ */
+ NEVER,
+ /**
+ * see {@link org.hibernate.FlushMode#MANUAL}
+ */
+ MANUAL,
+
+ /**
+ * Current flush mode of the persistence context at the time the query is executed
+ */
+ PERSISTENCE_CONTEXT
+}
\ No newline at end of file
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/FlushModeType.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/ForceDiscriminator.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/ForceDiscriminator.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/ForceDiscriminator.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/annotations/ForceDiscriminator.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,38 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * ForceDiscriminator flag
+ * To be placed at the root entity near @DiscriminatorColumn or @DiscriminatorFormula
+ *
+ * @author Serg Prasolov
+ */
+(a)Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME)
+public @interface ForceDiscriminator {}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/ForceDiscriminator.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/ForeignKey.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/ForeignKey.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/ForeignKey.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/ForeignKey.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,51 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+@Target({FIELD, METHOD, TYPE})
+@Retention(RUNTIME)
+
+/**
+ * Define the foreign key name
+ */
+public @interface ForeignKey {
+ /**
+ * Name of the foreign key. Used in OneToMany, ManyToOne, and OneToOne
+ * relationships. Used for the owning side in ManyToMany relationships
+ */
+ String name();
+
+ /**
+ * Used for the non-owning side of a ManyToMany relationship. Ignored
+ * in other relationships
+ */
+ String inverseName() default "";
+}
\ No newline at end of file
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/ForeignKey.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Formula.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Formula.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Formula.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Formula.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,42 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Formula. To be used as a replacement for @Column in most places
+ * The formula has to be a valid SQL fragment
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({METHOD, FIELD})
+@Retention(RUNTIME)
+public @interface Formula {
+ String value();
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/Formula.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Generated.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Generated.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Generated.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Generated.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,40 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * The annotated property is generated by the database
+ *
+ * @author Emmanuel Bernard
+ */
+(a)Target({ElementType.FIELD, ElementType.METHOD})
+(a)Retention(RetentionPolicy.RUNTIME)
+public @interface Generated {
+ GenerationTime value();
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/Generated.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/GenerationTime.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/GenerationTime.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/GenerationTime.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/GenerationTime.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,35 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+/**
+ * When should the generation occurs
+ *
+ * @author Emmanuel Bernard
+ */
+public enum GenerationTime {
+ NEVER,
+ INSERT,
+ ALWAYS
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/GenerationTime.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/GenericGenerator.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/GenericGenerator.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/GenericGenerator.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/annotations/GenericGenerator.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,53 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.*;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Generator annotation describing any kind of Hibernate
+ * generator in a detyped manner
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({PACKAGE, TYPE, METHOD, FIELD})
+@Retention(RUNTIME)
+public @interface GenericGenerator {
+ /**
+ * unique generator name
+ */
+ String name();
+ /**
+ * Generator strategy either a predefined Hibernate
+ * strategy or a fully qualified class name.
+ */
+ String strategy();
+ /**
+ * Optional generator parameters
+ */
+ Parameter[] parameters() default {};
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/GenericGenerator.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/GenericGenerators.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/GenericGenerators.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/GenericGenerators.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/annotations/GenericGenerators.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,43 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Array of generic generator definitions
+ *
+ * @author Paul Cowan
+ */
+@Target({PACKAGE, TYPE})
+@Retention(RUNTIME)
+public @interface GenericGenerators {
+ GenericGenerator[] value();
+}
+
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/GenericGenerators.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Immutable.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Immutable.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Immutable.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Immutable.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,44 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import java.lang.annotation.*;
+
+/**
+ * Mark an Entity or a Collection as immutable. No annotation means the element is
mutable.
+ * <p>
+ * An immutable entity may not be updated by the application. Updates to an immutable
+ * entity will be ignored, but no exception is thrown. @Immutable must be used
on root entities only.
+ * </p>
+ * <p>
+ * @Immutable placed on a collection makes the collection immutable, meaning
additions and
+ * deletions to and from the collection are not allowed. A
<i>HibernateException</i> is thrown in this case.
+ * </p>
+ *
+ * @author Emmanuel Bernard
+ */
+(a)java.lang.annotation.Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
+@Retention( RetentionPolicy.RUNTIME )
+public @interface Immutable {
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/Immutable.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Index.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Index.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Index.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Index.java 2010-07-08 23:41:23
UTC (rev 19921)
@@ -0,0 +1,43 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Define a DB index
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({FIELD, METHOD})
+@Retention(RUNTIME)
+public @interface Index {
+ String name();
+
+ String[] columnNames() default {};
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/Index.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/IndexColumn.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/IndexColumn.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/IndexColumn.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/IndexColumn.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,49 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Describe an index column of a List
+ * Prefer the standard {@link javax.persistence.OrderColumn} annotation
+ *
+ * @author Matthew Inger
+ */
+@Target({METHOD, FIELD})
+@Retention(RUNTIME)
+public @interface IndexColumn {
+ /** column name */
+ String name();
+ /** index in DB start from base */
+ int base() default 0;
+ /** is the index nullable */
+ boolean nullable() default true;
+ /** column definition, default to an appropriate integer */
+ String columnDefinition() default "";
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/IndexColumn.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/JoinColumnOrFormula.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/JoinColumnOrFormula.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/JoinColumnOrFormula.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/annotations/JoinColumnOrFormula.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,48 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates 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.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.persistence.JoinColumn;
+
+/**
+ * @author Sharath Reddy
+ */
+@Target({METHOD, FIELD})
+@Retention(RUNTIME)
+public @interface JoinColumnOrFormula {
+ JoinFormula formula() default @JoinFormula(value="",
referencedColumnName="");
+ JoinColumn column() default @JoinColumn();
+}
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/JoinColumnsOrFormulas.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/JoinColumnsOrFormulas.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/JoinColumnsOrFormulas.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/annotations/JoinColumnsOrFormulas.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,43 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates 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.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * @author Sharath Reddy
+ */
+@Target({METHOD, FIELD})
+@Retention(RUNTIME)
+public @interface JoinColumnsOrFormulas {
+ JoinColumnOrFormula [] value();
+}
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/JoinFormula.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/JoinFormula.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/JoinFormula.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/JoinFormula.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,47 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates 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.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * JoinFormula. To be used as a replacement for @JoinColumn in most places
+ * The formula has to be a valid SQL fragment
+ *
+ * @author Sharath Reddy
+ */
+@Target({METHOD, FIELD})
+@Retention(RUNTIME)
+public @interface JoinFormula {
+ String value();
+ String referencedColumnName() default "";
+}
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/LazyCollection.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/LazyCollection.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/LazyCollection.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/LazyCollection.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,40 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Define the lazy status of a collection
+ *
+ * @author Emmanuel Bernard
+ */
+(a)Target({ElementType.METHOD, ElementType.FIELD})
+(a)Retention(RetentionPolicy.RUNTIME)
+public @interface LazyCollection {
+ LazyCollectionOption value();
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/LazyCollection.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/LazyCollectionOption.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/LazyCollectionOption.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/LazyCollectionOption.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/annotations/LazyCollectionOption.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,38 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+/**
+ * Lazy options available for a collection
+ *
+ * @author Emmanuel Bernard
+ */
+public enum LazyCollectionOption {
+ /** eagerly load it */
+ FALSE,
+ /** load it when the state is requested */
+ TRUE,
+ /** prefer extra queries over fill collection loading */
+ EXTRA
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/LazyCollectionOption.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/LazyToOne.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/LazyToOne.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/LazyToOne.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/LazyToOne.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,41 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Define the lazy status of a ToOne association
+ * (ie OneToOne or ManyToOne)
+ *
+ * @author Emmanuel Bernard
+ */
+(a)Target({ElementType.METHOD, ElementType.FIELD})
+(a)Retention(RetentionPolicy.RUNTIME)
+public @interface LazyToOne {
+ LazyToOneOption value();
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/LazyToOne.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/LazyToOneOption.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/LazyToOneOption.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/LazyToOneOption.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/annotations/LazyToOneOption.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,45 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+/**
+ * Lazy options available for a ToOne association
+ *
+ * @author Emmanuel Bernard
+ */
+public enum LazyToOneOption {
+ /** eagerly load the association */
+ FALSE,
+ /**
+ * Lazy, give back a proxy which will be loaded when the state is requested
+ * This should be the prefered option
+ */
+ PROXY,
+ /** Lazy, give back the real object loaded when a reference is requested
+ * (Bytecode enhancement is mandatory for this option, fall back to PROXY
+ * if the class is not enhanced)
+ * This option should be avoided unless you can't afford the use of proxies
+ */
+ NO_PROXY
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/LazyToOneOption.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Loader.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Loader.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Loader.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Loader.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,45 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Loader Annotation for overwriting Hibernate default FIND method
+ *
+ * @author L�szl� Benke
+ */
+@Target( {TYPE, FIELD, METHOD} )
+@Retention( RUNTIME )
+public @interface Loader {
+ /**
+ * namedQuery to use for loading
+ */
+ String namedQuery() default "";
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/Loader.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/ManyToAny.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/ManyToAny.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/ManyToAny.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/ManyToAny.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,63 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.FIELD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import javax.persistence.Column;
+import javax.persistence.FetchType;
+import static javax.persistence.FetchType.EAGER;
+
+/**
+ * Defined a ToMany association pointing to different entity types.
+ * Matching the according entity type is doe through a metadata discriminator column
+ * This kind of mapping should be only marginal.
+ *
+ * @author Emmanuel Bernard
+ */
+(a)java.lang.annotation.Target({METHOD, FIELD})
+@Retention(RUNTIME)
+public @interface ManyToAny {
+ /**
+ * Metadata definition used.
+ * If defined, should point to a @AnyMetaDef name
+ * If not defined, the local (ie in the same field or property) @AnyMetaDef is used
+ */
+ String metaDef() default "";
+
+ /**
+ * Metadata dicriminator column description, This column will hold the meta value
corresponding to the
+ * targeted entity.
+ */
+ Column metaColumn();
+ /**
+ * Defines whether the value of the field or property should be lazily loaded or must
be
+ * eagerly fetched. The EAGER strategy is a requirement on the persistence provider
runtime
+ * that the value must be eagerly fetched. The LAZY strategy is applied when bytecode
+ * enhancement is used. If not specified, defaults to EAGER.
+ */
+ FetchType fetch() default FetchType.EAGER;
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/ManyToAny.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/MapKey.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/MapKey.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/MapKey.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/MapKey.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,58 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.FIELD;
+import javax.persistence.Column;
+
+/**
+ * Define the map key columns as an explicit column holding the map key
+ * This is completely different from {@link javax.persistence.MapKey} which use an
existing column
+ * This annotation and {@link javax.persistence.MapKey} are mutually exclusive
+ *
+ * @deprecated Use {@link javax.persistence.MapKeyColumn}
+ * This is the default behavior for Map properties marked as @OneToMany,
@ManyToMany
+ * or @ElementCollection
+ * @author Emmanuel Bernard
+ */
+@Target({METHOD, FIELD})
+@Retention(RUNTIME)
+@Deprecated
+public @interface MapKey {
+ Column[] columns() default {};
+ /**
+ * Represent the key class in a Map
+ * Only useful if the collection does not use generics
+ */
+ Class targetElement() default void.class;
+
+ /**
+ * The optional map key type. Guessed if default
+ */
+ Type type() default @Type(type = "");
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/MapKey.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/MapKeyManyToMany.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/MapKeyManyToMany.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/MapKeyManyToMany.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/annotations/MapKeyManyToMany.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,52 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import javax.persistence.JoinColumn;
+
+/**
+ * Define the map key columns as an explicit column holding the map key
+ * This is completely different from {@link javax.persistence.MapKey} which use an
existing column
+ * This annotation and {@link javax.persistence.MapKey} are mutually exclusive
+ *
+ * @deprecated Use {@link javax.persistence.MapKeyJoinColumn} {@link
javax.persistence.MapKeyJoinColumns}
+ * This is the default behavior for Map properties marked as @OneToMany,
@ManyToMany
+ * or @ElementCollection
+ * @author Emmanuel Bernard
+ */
+(a)Target({ElementType.METHOD, ElementType.FIELD})
+(a)Retention(RetentionPolicy.RUNTIME)
+@Deprecated
+public @interface MapKeyManyToMany {
+ JoinColumn[] joinColumns() default {};
+ /**
+ * Represent the key class in a Map
+ * Only useful if the collection does not use generics
+ */
+ Class targetEntity() default void.class;
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/MapKeyManyToMany.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/MetaValue.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/MetaValue.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/MetaValue.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/MetaValue.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,40 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+/**
+ * Represent a discriminator value associated to a given entity type
+ * @author Emmanuel Bernard
+ */
+public @interface MetaValue {
+ /**
+ * entity type
+ */
+ Class targetEntity();
+
+ /**
+ * discriminator value stored in database
+ */
+ String value();
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/MetaValue.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/NamedNativeQueries.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/NamedNativeQueries.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/NamedNativeQueries.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/annotations/NamedNativeQueries.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,42 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Extends {@link javax.persistence.NamedNativeQueries} to hold hibernate
NamedNativeQuery
+ * objects
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({TYPE, PACKAGE})
+@Retention(RUNTIME)
+public @interface NamedNativeQueries {
+ NamedNativeQuery[] value();
+}
\ No newline at end of file
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/NamedNativeQueries.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/NamedNativeQuery.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/NamedNativeQuery.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/NamedNativeQuery.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/annotations/NamedNativeQuery.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,65 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Extends {@link javax.persistence.NamedNativeQuery} with Hibernate features
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({TYPE, PACKAGE})
+@Retention(RUNTIME)
+public @interface NamedNativeQuery {
+ String name();
+
+ String query();
+
+ Class resultClass() default void.class;
+
+ String resultSetMapping() default ""; // name of SQLResultSetMapping
+ /** the flush mode for the query */
+ FlushModeType flushMode() default FlushModeType.PERSISTENCE_CONTEXT;
+ /** mark the query as cacheable or not */
+ boolean cacheable() default false;
+ /** the cache region to use */
+ String cacheRegion() default "";
+ /** the number of rows fetched by the JDBC Driver per roundtrip */
+ int fetchSize() default -1;
+ /**the query timeout in seconds*/
+ int timeout() default -1;
+
+ boolean callable() default false;
+ /**comment added to the SQL query, useful for the DBA */
+ String comment() default "";
+ /**the cache mode used for this query*/
+ CacheModeType cacheMode() default CacheModeType.NORMAL;
+ /**marks whether the results are fetched in read-only mode or not*/
+ boolean readOnly() default false;
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/NamedNativeQuery.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/NamedQueries.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/NamedQueries.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/NamedQueries.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/NamedQueries.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,43 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Extends {@link javax.persistence.NamedQueries} to hold hibernate NamedQuery
+ * objects
+ *
+ * @author Emmanuel Bernard
+ * @author Carlos Gonz�lez-Cadenas
+ */
+@Target({TYPE, PACKAGE})
+@Retention(RUNTIME)
+public @interface NamedQueries {
+ NamedQuery[] value();
+}
\ No newline at end of file
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/NamedQueries.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/NamedQuery.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/NamedQuery.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/NamedQuery.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/NamedQuery.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,62 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Extends {@link javax.persistence.NamedQuery} with Hibernate features
+ *
+ * @author Carlos Gonz�lez-Cadenas
+ */
+@Target({TYPE, PACKAGE})
+@Retention(RUNTIME)
+public @interface NamedQuery {
+
+ /** the name of the NamedQuery */
+ String name();
+ /** the Query String for the NamedQuery */
+ String query();
+ /** the flush mode for the query */
+ FlushModeType flushMode() default FlushModeType.PERSISTENCE_CONTEXT;
+ /** mark the query as cacheable or not */
+ boolean cacheable() default false;
+ /** the cache region to use */
+ String cacheRegion() default "";
+ /** the number of rows fetched by the JDBC Driver per roundtrip */
+ int fetchSize() default -1;
+ /**the query timeout in seconds*/
+ int timeout() default -1;
+ /**comment added to the SQL query, useful for the DBA */
+ String comment() default "";
+ /**the cache mode used for this query*/
+ CacheModeType cacheMode() default CacheModeType.NORMAL;
+ /**marks whether the results are fetched in read-only mode or not*/
+ boolean readOnly() default false;
+
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/NamedQuery.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/NaturalId.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/NaturalId.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/NaturalId.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/NaturalId.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,45 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+
+/**
+ * This specifies that a property is part of the natural id of the entity.
+ *
+ * @author Nicol�s Lichtmaier
+ */
+@Target( { METHOD, FIELD } )
+@Retention( RUNTIME )
+public @interface NaturalId {
+ /**
+ * If this natural id component is mutable or not.
+ */
+ boolean mutable() default false;
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/NaturalId.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/NotFound.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/NotFound.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/NotFound.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/NotFound.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,41 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Action to do when an element is not found on a association whiel beeing expected
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({METHOD, FIELD})
+@Retention(RUNTIME)
+public @interface NotFound {
+ NotFoundAction action() default NotFoundAction.EXCEPTION;
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/NotFound.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/NotFoundAction.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/NotFoundAction.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/NotFoundAction.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/NotFoundAction.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,40 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+/**
+ * Actoin to use when an element is not found in DB while beeing expected
+ *
+ * @author Emmanuel Bernard
+ */
+public enum NotFoundAction {
+ /**
+ * raise an exception when an element is not found (default and recommended)
+ */
+ EXCEPTION,
+ /**
+ * ignore the element when not found in DB
+ */
+ IGNORE
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/NotFoundAction.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/OnDelete.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/OnDelete.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/OnDelete.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/OnDelete.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,42 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.*;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+
+/**
+ * Strategy to use on collections, arrays and on joined subclasses delete
+ * OnDelete of secondary tables currently not supported.
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({METHOD, FIELD, TYPE})
+@Retention(RUNTIME)
+public @interface OnDelete {
+ OnDeleteAction action();
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/OnDelete.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/OnDeleteAction.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/OnDeleteAction.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/OnDeleteAction.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/OnDeleteAction.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,40 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+/**
+ * Possible actions on deletes
+ *
+ * @author Emmanuel Bernard
+ */
+public enum OnDeleteAction {
+ /**
+ * the default
+ */
+ NO_ACTION,
+ /**
+ * use cascade delete capabilities of the DD
+ */
+ CASCADE
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/OnDeleteAction.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/OptimisticLock.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/OptimisticLock.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/OptimisticLock.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/OptimisticLock.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Whether or not update entity's version on property's change
+ * If the annotation is not present, the property is involved in the optimistic lock
srategy (default)
+ *
+ * @author Logi Ragnarsson
+ */
+@Target( {ElementType.METHOD, ElementType.FIELD} )
+@Retention( RetentionPolicy.RUNTIME )
+public @interface OptimisticLock {
+
+ /**
+ * If true, the annotated property change will not trigger a version upgrade
+ */
+ boolean excluded();
+
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/OptimisticLock.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/OptimisticLockType.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/OptimisticLockType.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/OptimisticLockType.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/annotations/OptimisticLockType.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,49 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+/**
+ * Optimistic locking strategy
+ * VERSION is the default and recommanded one
+ *
+ * @author Emmanuel Bernard
+ */
+public enum OptimisticLockType {
+ /**
+ * no optimistic locking
+ */
+ NONE,
+ /**
+ * use a column version
+ */
+ VERSION,
+ /**
+ * dirty columns are compared
+ */
+ DIRTY,
+ /**
+ * all columns are compared
+ */
+ ALL
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/OptimisticLockType.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/OrderBy.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/OrderBy.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/OrderBy.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/OrderBy.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,42 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Order a collection using SQL ordering (not HQL ordering)
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({METHOD, FIELD})
+@Retention(RUNTIME)
+public @interface OrderBy {
+ /** SQL orderby clause */
+ String clause();
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/OrderBy.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/ParamDef.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/ParamDef.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/ParamDef.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/ParamDef.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,41 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * A parameter definition
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({})
+@Retention(RUNTIME)
+public @interface ParamDef {
+ String name();
+
+ String type();
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/ParamDef.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Parameter.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Parameter.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Parameter.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Parameter.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,41 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Parameter (basically key/value pattern)
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({})
+@Retention(RUNTIME)
+public @interface Parameter {
+ String name();
+
+ String value();
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/Parameter.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Parent.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Parent.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Parent.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Parent.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,40 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Reference the property as a pointer back to the owner (generally the owning entity)
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({METHOD, FIELD})
+@Retention(RUNTIME)
+public @interface Parent {
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/Parent.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Persister.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Persister.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Persister.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Persister.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,38 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import java.lang.annotation.*;
+
+/**
+ * Specify a custom persister.
+ *
+ * @author Shawn Clowater
+ */
+(a)java.lang.annotation.Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
+@Retention( RetentionPolicy.RUNTIME )
+public @interface Persister {
+ /** Custom persister */
+ Class impl();
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/Persister.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/PolymorphismType.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/PolymorphismType.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/PolymorphismType.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/annotations/PolymorphismType.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,40 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+/**
+ * Type of available polymorphism for a particular entity
+ *
+ * @author Emmanuel Bernard
+ */
+public enum PolymorphismType {
+ /**
+ * default, this entity is retrieved if any of its super entity is asked
+ */
+ IMPLICIT,
+ /**
+ * this entity is retrieved only if explicitly asked
+ */
+ EXPLICIT
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/PolymorphismType.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Proxy.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Proxy.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Proxy.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Proxy.java 2010-07-08 23:41:23
UTC (rev 19921)
@@ -0,0 +1,48 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Lazy and proxy configuration of a particular class
+ *
+ * @author Emmanuel Bernard
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+public @interface Proxy {
+ /**
+ * Whether this class is lazy or not (default to true)
+ */
+ boolean lazy() default true;
+
+ /**
+ * Proxy class or interface used. Default entity class name.
+ */
+ Class proxyClass() default void.class;
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/Proxy.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/ResultCheckStyle.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/ResultCheckStyle.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/ResultCheckStyle.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/annotations/ResultCheckStyle.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,53 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+/**
+ * Possible checks on Sql Insert, Delete, Update
+ *
+ * @author L�szl� Benke
+ */
+public enum ResultCheckStyle {
+ /**
+ * Do not perform checking. Either user simply does not want checking, or is
+ * indicating a {@link java.sql.CallableStatement} execution in which the
+ * checks are being performed explicitly and failures are handled through
+ * propogation of {@link java.sql.SQLException}s.
+ */
+ NONE,
+ /**
+ * Perform row-count checking. Row counts are the int values returned by both
+ * {@link java.sql.PreparedStatement#executeUpdate()} and
+ * {@link java.sql.Statement#executeBatch()}. These values are checked
+ * against some expected count.
+ */
+ COUNT,
+ /**
+ * Essentially the same as {@link #COUNT} except that the row count actually
+ * comes from an output parameter registered as part of a
+ * {@link java.sql.CallableStatement}. This style explicitly prohibits
+ * statement batching from being used...
+ */
+ PARAM
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/ResultCheckStyle.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/SQLDelete.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/SQLDelete.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/SQLDelete.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/SQLDelete.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,55 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * SqlDelete Annotation for overwriting Hibernate default DELETE method
+ *
+ * @author L�szl� Benke
+ */
+@Target( {TYPE, FIELD, METHOD} )
+@Retention( RUNTIME )
+public @interface SQLDelete {
+ /**
+ * Procedure name or DELETE STATEMENT
+ */
+ String sql();
+
+ /**
+ * Is the statement using stored procedure or not
+ */
+ boolean callable() default false;
+
+ /**
+ * For persistence operation what style of determining results (success/failure) is to
be used.
+ */
+ ResultCheckStyle check() default ResultCheckStyle.NONE;
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/SQLDelete.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/SQLDeleteAll.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/SQLDeleteAll.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/SQLDeleteAll.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/SQLDeleteAll.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,56 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * SqlDelete Annotation for overwriting Hibernate default DELETE ALL method
+ *
+ * @author L�szl� Benke
+ */
+@Target( {TYPE, FIELD, METHOD} )
+@Retention( RetentionPolicy.RUNTIME )
+public @interface SQLDeleteAll {
+ /**
+ * Procedure name or DELETE STATEMENT
+ */
+ String sql();
+
+ /**
+ * Is the statement using stored procedure or not
+ */
+ boolean callable() default false;
+
+ /**
+ * For persistence operation what style of determining results (success/failure) is to
be used.
+ */
+ ResultCheckStyle check() default ResultCheckStyle.NONE;
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/SQLDeleteAll.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/SQLInsert.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/SQLInsert.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/SQLInsert.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/SQLInsert.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,55 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * SqlInsert Annotation for overwriting Hibernate default INSERT INTO method
+ *
+ * @author L�szl� Benke
+ */
+@Target( {TYPE, FIELD, METHOD} )
+@Retention( RUNTIME )
+public @interface SQLInsert {
+ /**
+ * Procedure name or INSERT STATEMENT
+ */
+ String sql();
+
+ /**
+ * Is the statement using stored procedure or not
+ */
+ boolean callable() default false;
+
+ /**
+ * For persistence operation what style of determining results (success/failure) is to
be used.
+ */
+ ResultCheckStyle check() default ResultCheckStyle.NONE;
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/SQLInsert.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/SQLUpdate.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/SQLUpdate.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/SQLUpdate.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/SQLUpdate.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,56 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * SqlUpdate Annotation for overwriting Hibernate default UPDATE method
+ *
+ * @author L�szl� Benke
+ */
+@Target( {TYPE, FIELD, METHOD} )
+@Retention( RUNTIME )
+public @interface SQLUpdate {
+
+ /**
+ * Procedure name or UPDATE STATEMENT
+ */
+ String sql();
+
+ /**
+ * Is the statement using stored procedure or not
+ */
+ boolean callable() default false;
+
+ /**
+ * For persistence operation what style of determining results (success/failure) is to
be used.
+ */
+ ResultCheckStyle check() default ResultCheckStyle.NONE;
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/SQLUpdate.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Sort.java (from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/Sort.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Sort.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Sort.java 2010-07-08 23:41:23
UTC (rev 19921)
@@ -0,0 +1,51 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Collection sort
+ * (Java level sorting)
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({METHOD, FIELD})
+@Retention(RUNTIME)
+public @interface Sort {
+ /**
+ * sort type
+ */
+ SortType type() default SortType.UNSORTED;
+ /**
+ * Sort comparator implementation
+ */
+ //TODO find a way to use Class<Comparator>
+
+ Class comparator() default void.class;
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/Sort.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/SortType.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/SortType.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/SortType.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/SortType.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,35 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+/**
+ * Sort strategies
+ *
+ * @author Emmanuel Bernard
+ */
+public enum SortType {
+ UNSORTED,
+ NATURAL,
+ COMPARATOR
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/SortType.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Subselect.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Subselect.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Subselect.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Subselect.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,18 @@
+package org.hibernate.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Map an immutable and read-only entity to a given SQL subselect expression:
+ * @author Sharath Reddy
+ *
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+public @interface Subselect {
+ String value();
+}
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Synchronize.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Synchronize.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Synchronize.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Synchronize.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,24 @@
+package org.hibernate.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Ensures that auto-flush happens correctly and that queries against the derived
+ * entity do not return stale data.
+ *
+ * Mostly used with Subselect.
+ *
+ * @author Sharath Reddy
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+public @interface Synchronize {
+ /**
+ * Table names
+ */
+ String [] value();
+}
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Table.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Table.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Table.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Table.java 2010-07-08 23:41:23
UTC (rev 19921)
@@ -0,0 +1,108 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Complementary information to a table either primary or secondary
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({TYPE})
+@Retention(RUNTIME)
+public @interface Table {
+ /**
+ * name of the targeted table
+ */
+ String appliesTo();
+
+ /**
+ * Indexes
+ */
+ Index[] indexes() default {};
+
+ /**
+ * define a table comment
+ */
+ String comment() default "";
+
+ /**
+ * Defines the Foreign Key name of a secondary table
+ * pointing back to the primary table
+ */
+ ForeignKey foreignKey() default @ForeignKey( name="" );
+
+ /**
+ * If set to JOIN, the default, Hibernate will use an inner join to retrieve a
+ * secondary table defined by a class or its superclasses and an outer join for a
+ * secondary table defined by a subclass.
+ * If set to select then Hibernate will use a
+ * sequential select for a secondary table defined on a subclass, which will be issued
only if a row
+ * turns out to represent an instance of the subclass. Inner joins will still be used to
retrieve a
+ * secondary defined by the class and its superclasses.
+ *
+ * <b>Only applies to secondary tables</b>
+ */
+ FetchMode fetch() default FetchMode.JOIN;
+
+ /**
+ * If true, Hibernate will not try to insert or update the properties defined by this
join.
+ *
+ * <b>Only applies to secondary tables</b>
+ */
+ boolean inverse() default false;
+
+ /**
+ * If enabled, Hibernate will insert a row only if the properties defined by this join
are non-null
+ * and will always use an outer join to retrieve the properties.
+ *
+ * <b>Only applies to secondary tables</b>
+ */
+ boolean optional() default true;
+
+ /**
+ * Defines a custom SQL insert statement
+ *
+ * <b>Only applies to secondary tables</b>
+ */
+ SQLInsert sqlInsert() default @SQLInsert(sql="");
+
+ /**
+ * Defines a custom SQL update statement
+ *
+ * <b>Only applies to secondary tables</b>
+ */
+ SQLUpdate sqlUpdate() default @SQLUpdate(sql="");
+
+ /**
+ * Defines a custom SQL delete statement
+ *
+ * <b>Only applies to secondary tables</b>
+ */
+ SQLDelete sqlDelete() default @SQLDelete(sql="");
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/Table.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Tables.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Tables.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Tables.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Tables.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,41 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Plural of Table
+ *
+ * @author Emmanuel Bernard
+ * @see Table
+ */
+@Target({TYPE})
+@Retention(RUNTIME)
+public @interface Tables {
+ Table[] value();
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/Tables.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Target.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Target.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Target.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Target.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,39 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Define an explicit target,a voiding reflection and generics resolving
+ *
+ * @author Emmanuel Bernard
+ */
+(a)java.lang.annotation.Target({ElementType.FIELD, ElementType.METHOD})
+@Retention( RetentionPolicy.RUNTIME )
+public @interface Target {
+ Class value();
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/Target.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Tuplizer.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Tuplizer.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Tuplizer.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Tuplizer.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,43 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import java.lang.annotation.*;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+
+/**
+ * Define a tuplizer for an entity or a component
+ * @author Emmanuel Bernard
+ */
+(a)java.lang.annotation.Target( {TYPE, FIELD, METHOD} )
+@Retention( RUNTIME )
+public @interface Tuplizer {
+ /** tuplizer implementation */
+ Class impl();
+ /** either pojo, dynamic-map or dom4j� */
+ String entityMode() default "pojo";
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/Tuplizer.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Tuplizers.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Tuplizers.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Tuplizers.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Tuplizers.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,38 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Define a set of tuplizer for an entity or a component
+ * @author Emmanuel Bernard
+ */
+(a)java.lang.annotation.Target( {ElementType.TYPE, ElementType.FIELD, ElementType.METHOD}
)
+@Retention( RetentionPolicy.RUNTIME )
+public @interface Tuplizers {
+ Tuplizer[] value();
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/Tuplizers.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Type.java (from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/Type.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Type.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Type.java 2010-07-08 23:41:23
UTC (rev 19921)
@@ -0,0 +1,43 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * hibernate type
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({FIELD, METHOD})
+@Retention(RUNTIME)
+public @interface Type {
+ String type();
+
+ Parameter[] parameters() default {};
+}
\ No newline at end of file
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/Type.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/TypeDef.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/TypeDef.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/TypeDef.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/TypeDef.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,44 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Type definition
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({TYPE, PACKAGE})
+@Retention(RUNTIME)
+public @interface TypeDef {
+ String name() default "";
+ Class<?> defaultForType() default void.class;
+ Class<?> typeClass();
+ Parameter[] parameters() default {};
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/TypeDef.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/TypeDefs.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/TypeDefs.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/TypeDefs.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/TypeDefs.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,41 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Type definition array
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({TYPE, PACKAGE})
+@Retention(RUNTIME)
+public @interface TypeDefs {
+ TypeDef[] value();
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/TypeDefs.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/Where.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/annotations/Where.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/Where.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/Where.java 2010-07-08 23:41:23
UTC (rev 19921)
@@ -0,0 +1,41 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import static java.lang.annotation.ElementType.*;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+/**
+ * Where clause to add to the element Entity or target entity of a collection
+ * The clause is written in SQL
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({TYPE, METHOD, FIELD})
+@Retention(RUNTIME)
+public @interface Where {
+ String clause();
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/annotations/Where.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/annotations/WhereJoinTable.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/annotations/WhereJoinTable.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/annotations/WhereJoinTable.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/annotations/WhereJoinTable.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,41 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.annotations;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Where clause to add to the colleciton join table
+ * The clause is written in SQL
+ *
+ * @author Emmanuel Bernard
+ */
+(a)Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
+(a)Retention(RetentionPolicy.RUNTIME)
+public @interface WhereJoinTable {
+ String clause();
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/annotations/WhereJoinTable.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,389 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.AssociationOverride;
+import javax.persistence.AssociationOverrides;
+import javax.persistence.AttributeOverride;
+import javax.persistence.AttributeOverrides;
+import javax.persistence.Column;
+import javax.persistence.Embeddable;
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.MappedSuperclass;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.annotations.common.reflection.XAnnotatedElement;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.util.StringHelper;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public abstract class AbstractPropertyHolder implements PropertyHolder {
+ protected AbstractPropertyHolder parent;
+ private Map<String, Column[]> holderColumnOverride;
+ private Map<String, Column[]> currentPropertyColumnOverride;
+ private Map<String, JoinColumn[]> holderJoinColumnOverride;
+ private Map<String, JoinColumn[]> currentPropertyJoinColumnOverride;
+ private Map<String, JoinTable> holderJoinTableOverride;
+ private Map<String, JoinTable> currentPropertyJoinTableOverride;
+ private String path;
+ private ExtendedMappings mappings;
+ private Boolean isInIdClass;
+
+
+ public AbstractPropertyHolder(
+ String path, PropertyHolder parent, XClass clazzToProcess, ExtendedMappings mappings
+ ) {
+ this.path = path;
+ this.parent = (AbstractPropertyHolder) parent;
+ this.mappings = mappings;
+ buildHierarchyColumnOverride( clazzToProcess );
+ }
+
+
+ public boolean isInIdClass() {
+ return isInIdClass != null ? isInIdClass : parent != null ? parent.isInIdClass() :
false;
+ }
+
+ public void setInIdClass(Boolean isInIdClass) {
+ this.isInIdClass = isInIdClass;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ protected ExtendedMappings getMappings() {
+ return mappings;
+ }
+
+ /**
+ * property can be null
+ */
+ protected void setCurrentProperty(XProperty property) {
+ if ( property == null ) {
+ this.currentPropertyColumnOverride = null;
+ this.currentPropertyJoinColumnOverride = null;
+ this.currentPropertyJoinTableOverride = null;
+ }
+ else {
+ this.currentPropertyColumnOverride = buildColumnOverride(
+ property,
+ getPath()
+ );
+ if ( this.currentPropertyColumnOverride.size() == 0 ) {
+ this.currentPropertyColumnOverride = null;
+ }
+ this.currentPropertyJoinColumnOverride = buildJoinColumnOverride(
+ property,
+ getPath()
+ );
+ if ( this.currentPropertyJoinColumnOverride.size() == 0 ) {
+ this.currentPropertyJoinColumnOverride = null;
+ }
+ this.currentPropertyJoinTableOverride = buildJoinTableOverride(
+ property,
+ getPath()
+ );
+ if ( this.currentPropertyJoinTableOverride.size() == 0 ) {
+ this.currentPropertyJoinTableOverride = null;
+ }
+ }
+ }
+
+ /**
+ * Get column overriding, property first, then parent, then holder
+ * replace the placeholder 'collection&&element' with nothing
+ *
+ * These rules are here to support both JPA 2 and legacy overriding rules.
+ *
+ */
+ public Column[] getOverriddenColumn(String propertyName) {
+ Column[] result = getExactOverriddenColumn( propertyName );
+ if (result == null) {
+ //the commented code can be useful if people use the new prefixes on old mappings and
vice versa
+ // if we enable them:
+ // WARNING: this can conflict with user's expectations if:
+ // - the property uses some restricted values
+ // - the user has overridden the column
+ // also change getOverriddenJoinColumn and getOverriddenJoinTable as well
+
+// if ( propertyName.contains( ".key." ) ) {
+// //support for legacy @AttributeOverride declarations
+// //TODO cache the underlying regexp
+// result = getExactOverriddenColumn( propertyName.replace( ".key.",
".index." ) );
+// }
+// if ( result == null && propertyName.endsWith( ".key" ) ) {
+// //support for legacy @AttributeOverride declarations
+// //TODO cache the underlying regexp
+// result = getExactOverriddenColumn(
+// propertyName.substring( 0, propertyName.length() - ".key".length() ) +
".index"
+// );
+// }
+// if ( result == null && propertyName.contains( ".value." ) ) {
+// //support for legacy @AttributeOverride declarations
+// //TODO cache the underlying regexp
+// result = getExactOverriddenColumn( propertyName.replace( ".value.",
".element." ) );
+// }
+// if ( result == null && propertyName.endsWith( ".value" ) ) {
+// //support for legacy @AttributeOverride declarations
+// //TODO cache the underlying regexp
+// result = getExactOverriddenColumn(
+// propertyName.substring( 0, propertyName.length() - ".value".length() )
+ ".element"
+// );
+// }
+ if ( result == null && propertyName.contains(
".collection&&element." ) ) {
+ //support for non map collections where no prefix is needed
+ //TODO cache the underlying regexp
+ result = getExactOverriddenColumn( propertyName.replace(
".collection&&element.", "." ) );
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Get column overriding, property first, then parent, then holder
+ * find the overridden rules from the exact property name.
+ */
+ private Column[] getExactOverriddenColumn(String propertyName) {
+ Column[] override = null;
+ if ( parent != null ) {
+ override = parent.getExactOverriddenColumn( propertyName );
+ }
+ if ( override == null && currentPropertyColumnOverride != null ) {
+ override = currentPropertyColumnOverride.get( propertyName );
+ }
+ if ( override == null && holderColumnOverride != null ) {
+ override = holderColumnOverride.get( propertyName );
+ }
+ return override;
+ }
+
+ /**
+ * Get column overriding, property first, then parent, then holder
+ * replace the placeholder 'collection&&element' with nothing
+ *
+ * These rules are here to support both JPA 2 and legacy overriding rules.
+ *
+ */
+ public JoinColumn[] getOverriddenJoinColumn(String propertyName) {
+ JoinColumn[] result = getExactOverriddenJoinColumn( propertyName );
+ if ( result == null && propertyName.contains(
".collection&&element." ) ) {
+ //support for non map collections where no prefix is needed
+ //TODO cache the underlying regexp
+ result = getExactOverriddenJoinColumn( propertyName.replace(
".collection&&element.", "." ) );
+ }
+ return result;
+ }
+
+ /**
+ * Get column overriding, property first, then parent, then holder
+ */
+ private JoinColumn[] getExactOverriddenJoinColumn(String propertyName) {
+ JoinColumn[] override = null;
+ if ( parent != null ) {
+ override = parent.getExactOverriddenJoinColumn( propertyName );
+ }
+ if ( override == null && currentPropertyJoinColumnOverride != null ) {
+ override = currentPropertyJoinColumnOverride.get( propertyName );
+ }
+ if ( override == null && holderJoinColumnOverride != null ) {
+ override = holderJoinColumnOverride.get( propertyName );
+ }
+ return override;
+ }
+
+ /**
+ * Get column overriding, property first, then parent, then holder
+ * replace the placeholder 'collection&&element' with nothing
+ *
+ * These rules are here to support both JPA 2 and legacy overriding rules.
+ *
+ */
+ public JoinTable getJoinTable(XProperty property) {
+ final String propertyName = StringHelper.qualify( getPath(), property.getName() );
+ JoinTable result = getOverriddenJoinTable( propertyName );
+ if (result == null) {
+ result = property.getAnnotation( JoinTable.class );
+ }
+ return result;
+ }
+
+ /**
+ * Get column overriding, property first, then parent, then holder
+ * replace the placeholder 'collection&&element' with nothing
+ *
+ * These rules are here to support both JPA 2 and legacy overriding rules.
+ *
+ */
+ public JoinTable getOverriddenJoinTable(String propertyName) {
+ JoinTable result = getExactOverriddenJoinTable( propertyName );
+ if ( result == null && propertyName.contains(
".collection&&element." ) ) {
+ //support for non map collections where no prefix is needed
+ //TODO cache the underlying regexp
+ result = getExactOverriddenJoinTable( propertyName.replace(
".collection&&element.", "." ) );
+ }
+ return result;
+ }
+
+ /**
+ * Get column overriding, property first, then parent, then holder
+ */
+ private JoinTable getExactOverriddenJoinTable(String propertyName) {
+ JoinTable override = null;
+ if ( parent != null ) {
+ override = parent.getExactOverriddenJoinTable( propertyName );
+ }
+ if ( override == null && currentPropertyJoinTableOverride != null ) {
+ override = currentPropertyJoinTableOverride.get( propertyName );
+ }
+ if ( override == null && holderJoinTableOverride != null ) {
+ override = holderJoinTableOverride.get( propertyName );
+ }
+ return override;
+ }
+
+ private void buildHierarchyColumnOverride(XClass element) {
+ XClass current = element;
+ Map<String, Column[]> columnOverride = new HashMap<String, Column[]>();
+ Map<String, JoinColumn[]> joinColumnOverride = new HashMap<String,
JoinColumn[]>();
+ Map<String, JoinTable> joinTableOverride = new HashMap<String,
JoinTable>();
+ while ( current != null && !mappings.getReflectionManager().toXClass(
Object.class ).equals( current ) ) {
+ if ( current.isAnnotationPresent( Entity.class ) || current.isAnnotationPresent(
MappedSuperclass.class )
+ || current.isAnnotationPresent( Embeddable.class ) ) {
+ //FIXME is embeddable override?
+ Map<String, Column[]> currentOverride = buildColumnOverride( current, getPath()
);
+ Map<String, JoinColumn[]> currentJoinOverride = buildJoinColumnOverride(
current, getPath() );
+ Map<String, JoinTable> currentJoinTableOverride = buildJoinTableOverride(
current, getPath() );
+ currentOverride.putAll( columnOverride ); //subclasses have precedence over
superclasses
+ currentJoinOverride.putAll( joinColumnOverride ); //subclasses have precedence over
superclasses
+ currentJoinOverride.putAll( joinColumnOverride ); //subclasses have precedence over
superclasses
+ columnOverride = currentOverride;
+ joinColumnOverride = currentJoinOverride;
+ joinTableOverride = currentJoinTableOverride;
+ }
+ current = current.getSuperclass();
+ }
+
+ holderColumnOverride = columnOverride.size() > 0 ? columnOverride : null;
+ holderJoinColumnOverride = joinColumnOverride.size() > 0 ? joinColumnOverride :
null;
+ holderJoinTableOverride = joinTableOverride.size() > 0 ? joinTableOverride : null;
+ }
+
+ private static Map<String, Column[]> buildColumnOverride(XAnnotatedElement
element, String path) {
+ Map<String, Column[]> columnOverride = new HashMap<String, Column[]>();
+ if ( element == null ) return columnOverride;
+ AttributeOverride singleOverride = element.getAnnotation( AttributeOverride.class );
+ AttributeOverrides multipleOverrides = element.getAnnotation( AttributeOverrides.class
);
+ AttributeOverride[] overrides;
+ if ( singleOverride != null ) {
+ overrides = new AttributeOverride[] { singleOverride };
+ }
+ else if ( multipleOverrides != null ) {
+ overrides = multipleOverrides.value();
+ }
+ else {
+ overrides = null;
+ }
+
+ //fill overridden columns
+ if ( overrides != null ) {
+ for (AttributeOverride depAttr : overrides) {
+ columnOverride.put(
+ StringHelper.qualify( path, depAttr.name() ),
+ new Column[] { depAttr.column() }
+ );
+ }
+ }
+ return columnOverride;
+ }
+
+ private static Map<String, JoinColumn[]> buildJoinColumnOverride(XAnnotatedElement
element, String path) {
+ Map<String, JoinColumn[]> columnOverride = new HashMap<String,
JoinColumn[]>();
+ if ( element == null ) return columnOverride;
+ AssociationOverride singleOverride = element.getAnnotation( AssociationOverride.class
);
+ AssociationOverrides multipleOverrides = element.getAnnotation(
AssociationOverrides.class );
+ AssociationOverride[] overrides;
+ if ( singleOverride != null ) {
+ overrides = new AssociationOverride[] { singleOverride };
+ }
+ else if ( multipleOverrides != null ) {
+ overrides = multipleOverrides.value();
+ }
+ else {
+ overrides = null;
+ }
+
+ //fill overridden columns
+ if ( overrides != null ) {
+ for (AssociationOverride depAttr : overrides) {
+ columnOverride.put(
+ StringHelper.qualify( path, depAttr.name() ),
+ depAttr.joinColumns()
+ );
+ }
+ }
+ return columnOverride;
+ }
+
+ private static Map<String, JoinTable> buildJoinTableOverride(XAnnotatedElement
element, String path) {
+ Map<String, JoinTable> tableOverride = new HashMap<String, JoinTable>();
+ if ( element == null ) return tableOverride;
+ AssociationOverride singleOverride = element.getAnnotation( AssociationOverride.class
);
+ AssociationOverrides multipleOverrides = element.getAnnotation(
AssociationOverrides.class );
+ AssociationOverride[] overrides;
+ if ( singleOverride != null ) {
+ overrides = new AssociationOverride[] { singleOverride };
+ }
+ else if ( multipleOverrides != null ) {
+ overrides = multipleOverrides.value();
+ }
+ else {
+ overrides = null;
+ }
+
+ //fill overridden tables
+ if ( overrides != null ) {
+ for (AssociationOverride depAttr : overrides) {
+ if ( depAttr.joinColumns().length == 0 ) {
+ tableOverride.put(
+ StringHelper.qualify( path, depAttr.name() ),
+ depAttr.joinTable()
+ );
+ }
+ }
+ }
+ return tableOverride;
+ }
+
+ public void setParentProperty(String parentProperty) {
+ throw new AssertionFailure( "Setting the parent property to a non component"
);
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/AccessType.java (from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/AccessType.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/AccessType.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/AccessType.java 2010-07-08 23:41:23
UTC (rev 19921)
@@ -0,0 +1,85 @@
+// $Id$
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+/**
+ * Enum defining deifferent access strategies for accessing entity values.
+ *
+ * @author Hardy Ferentschik
+ */
+public enum AccessType {
+ /**
+ * Default access strategy is property
+ */
+ DEFAULT( "property" ),
+
+ /**
+ * Access to value via property
+ */
+ PROPERTY( "property" ),
+
+ /**
+ * Access to value via field
+ */
+ FIELD( "field" );
+
+ private final String accessType;
+
+ AccessType(String type) {
+ this.accessType = type;
+ }
+
+ public String getType() {
+ return accessType;
+ }
+
+ public static AccessType getAccessStrategy(String type) {
+ if ( type == null ) {
+ return DEFAULT;
+ }
+ else if ( FIELD.getType().equals( type ) ) {
+ return FIELD;
+ }
+ else if ( PROPERTY.getType().equals( type ) ) {
+ return PROPERTY;
+ }
+ else {
+ // TODO historically if the type string could not be matched default access was used.
Maybe this should be an exception though!?
+ return DEFAULT;
+ }
+ }
+
+ public static AccessType getAccessStrategy(javax.persistence.AccessType type) {
+ if ( javax.persistence.AccessType.PROPERTY.equals( type ) ) {
+ return PROPERTY;
+ }
+ else if ( javax.persistence.AccessType.FIELD.equals( type ) ) {
+ return FIELD;
+ }
+ else {
+ return DEFAULT;
+ }
+ }
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/cfg/AccessType.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/AnnotatedClassType.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotatedClassType.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/AnnotatedClassType.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/AnnotatedClassType.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,48 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+/**
+ * Type of annotation of a class will give its type
+ *
+ * @author Emmanuel Bernard
+ */
+public enum AnnotatedClassType {
+ /**
+ * has no revelent top level annotation
+ */
+ NONE,
+ /**
+ * has @Entity annotation
+ */
+ ENTITY,
+ /**
+ * has a @Embeddable annotation
+ */
+ EMBEDDABLE,
+ /**
+ * has @EmbeddedSuperclass annotation
+ */
+ EMBEDDABLE_SUPERCLASS
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/AnnotatedClassType.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/AnnotationBinder.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/AnnotationBinder.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/AnnotationBinder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,2982 @@
+// $Id$
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import javax.persistence.Basic;
+import javax.persistence.Cacheable;
+import javax.persistence.CollectionTable;
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorType;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.ElementCollection;
+import javax.persistence.Embeddable;
+import javax.persistence.Embedded;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.InheritanceType;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.MapKey;
+import javax.persistence.MapKeyColumn;
+import javax.persistence.MapKeyJoinColumn;
+import javax.persistence.MapKeyJoinColumns;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.MapsId;
+import javax.persistence.NamedNativeQueries;
+import javax.persistence.NamedNativeQuery;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.OrderColumn;
+import javax.persistence.PrimaryKeyJoinColumn;
+import javax.persistence.PrimaryKeyJoinColumns;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.SharedCacheMode;
+import javax.persistence.SqlResultSetMapping;
+import javax.persistence.SqlResultSetMappings;
+import javax.persistence.Table;
+import javax.persistence.TableGenerator;
+import javax.persistence.UniqueConstraint;
+import javax.persistence.Version;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.AssertionFailure;
+import org.hibernate.EntityMode;
+import org.hibernate.FetchMode;
+import org.hibernate.MappingException;
+import org.hibernate.annotations.BatchSize;
+import org.hibernate.annotations.Cache;
+import org.hibernate.annotations.CacheConcurrencyStrategy;
+import org.hibernate.annotations.Cascade;
+import org.hibernate.annotations.CascadeType;
+import org.hibernate.annotations.Check;
+import org.hibernate.annotations.CollectionId;
+import org.hibernate.annotations.CollectionOfElements;
+import org.hibernate.annotations.Columns;
+import org.hibernate.annotations.Fetch;
+import org.hibernate.annotations.FetchProfile;
+import org.hibernate.annotations.FetchProfiles;
+import org.hibernate.annotations.Filter;
+import org.hibernate.annotations.FilterDef;
+import org.hibernate.annotations.FilterDefs;
+import org.hibernate.annotations.Filters;
+import org.hibernate.annotations.ForeignKey;
+import org.hibernate.annotations.Formula;
+import org.hibernate.annotations.GenericGenerator;
+import org.hibernate.annotations.GenericGenerators;
+import org.hibernate.annotations.Index;
+import org.hibernate.annotations.LazyToOne;
+import org.hibernate.annotations.LazyToOneOption;
+import org.hibernate.annotations.ManyToAny;
+import org.hibernate.annotations.NaturalId;
+import org.hibernate.annotations.NotFound;
+import org.hibernate.annotations.NotFoundAction;
+import org.hibernate.annotations.OnDelete;
+import org.hibernate.annotations.OnDeleteAction;
+import org.hibernate.annotations.OrderBy;
+import org.hibernate.annotations.ParamDef;
+import org.hibernate.annotations.Parameter;
+import org.hibernate.annotations.Parent;
+import org.hibernate.annotations.Proxy;
+import org.hibernate.annotations.Sort;
+import org.hibernate.annotations.Tuplizer;
+import org.hibernate.annotations.Tuplizers;
+import org.hibernate.annotations.TypeDef;
+import org.hibernate.annotations.TypeDefs;
+import org.hibernate.annotations.Where;
+import org.hibernate.annotations.common.reflection.ReflectionManager;
+import org.hibernate.annotations.common.reflection.XAnnotatedElement;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XMethod;
+import org.hibernate.annotations.common.reflection.XPackage;
+import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.cache.RegionFactory;
+import org.hibernate.cfg.annotations.CollectionBinder;
+import org.hibernate.cfg.annotations.EntityBinder;
+import org.hibernate.cfg.annotations.MapKeyColumnDelegator;
+import org.hibernate.cfg.annotations.MapKeyJoinColumnDelegator;
+import org.hibernate.cfg.annotations.Nullability;
+import org.hibernate.cfg.annotations.PropertyBinder;
+import org.hibernate.cfg.annotations.QueryBinder;
+import org.hibernate.cfg.annotations.SimpleValueBinder;
+import org.hibernate.cfg.annotations.TableBinder;
+import org.hibernate.engine.FilterDefinition;
+import org.hibernate.engine.Versioning;
+import org.hibernate.id.MultipleHiLoPerTableGenerator;
+import org.hibernate.id.PersistentIdentifierGenerator;
+import org.hibernate.id.SequenceHiLoGenerator;
+import org.hibernate.id.TableHiLoGenerator;
+import org.hibernate.id.enhanced.SequenceStyleGenerator;
+import org.hibernate.mapping.Any;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.DependantValue;
+import org.hibernate.mapping.IdGenerator;
+import org.hibernate.mapping.Join;
+import org.hibernate.mapping.JoinedSubclass;
+import org.hibernate.mapping.KeyValue;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.RootClass;
+import org.hibernate.mapping.SimpleValue;
+import org.hibernate.mapping.SingleTableSubclass;
+import org.hibernate.mapping.Subclass;
+import org.hibernate.mapping.ToOne;
+import org.hibernate.mapping.UnionSubclass;
+import org.hibernate.persister.entity.JoinedSubclassEntityPersister;
+import org.hibernate.persister.entity.SingleTableEntityPersister;
+import org.hibernate.persister.entity.UnionSubclassEntityPersister;
+
+/**
+ * JSR 175 annotation binder which reads the annotations from classes, applies the
+ * principles of the EJB3 spec and produces the Hibernate configuration-time metamodel
+ * (the classes in the {@code org.hibernate.mapping} package)
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+@SuppressWarnings("unchecked")
+public final class AnnotationBinder {
+
+ /*
+ * Some design description
+ * I tried to remove any link to annotation except from the 2 first level of
+ * method call.
+ * It'll enable to:
+ * - facilitate annotation overriding
+ * - mutualize one day xml and annotation binder (probably a dream though)
+ * - split this huge class in smaller mapping oriented classes
+ *
+ * bindSomething usually create the mapping container and is accessed by one of the 2
first level method
+ * makeSomething usually create the mapping container and is accessed by
bindSomething[else]
+ * fillSomething take the container into parameter and fill it.
+ */
+
+ private AnnotationBinder() {
+ }
+
+ private static final Logger log = LoggerFactory.getLogger( AnnotationBinder.class );
+
+ public static void bindDefaults(ExtendedMappings mappings) {
+ Map defaults = mappings.getReflectionManager().getDefaults();
+ {
+ List<SequenceGenerator> anns = ( List<SequenceGenerator> ) defaults.get(
SequenceGenerator.class );
+ if ( anns != null ) {
+ for ( SequenceGenerator ann : anns ) {
+ IdGenerator idGen = buildIdGenerator( ann, mappings );
+ if ( idGen != null ) {
+ mappings.addDefaultGenerator( idGen );
+ }
+ }
+ }
+ }
+ {
+ List<TableGenerator> anns = ( List<TableGenerator> ) defaults.get(
TableGenerator.class );
+ if ( anns != null ) {
+ for ( TableGenerator ann : anns ) {
+ IdGenerator idGen = buildIdGenerator( ann, mappings );
+ if ( idGen != null ) {
+ mappings.addDefaultGenerator( idGen );
+ }
+ }
+ }
+ }
+ {
+ List<NamedQuery> anns = ( List<NamedQuery> ) defaults.get(
NamedQuery.class );
+ if ( anns != null ) {
+ for ( NamedQuery ann : anns ) {
+ QueryBinder.bindQuery( ann, mappings, true );
+ }
+ }
+ }
+ {
+ List<NamedNativeQuery> anns = ( List<NamedNativeQuery> ) defaults.get(
NamedNativeQuery.class );
+ if ( anns != null ) {
+ for ( NamedNativeQuery ann : anns ) {
+ QueryBinder.bindNativeQuery( ann, mappings, true );
+ }
+ }
+ }
+ {
+ List<SqlResultSetMapping> anns = ( List<SqlResultSetMapping> )
defaults.get( SqlResultSetMapping.class );
+ if ( anns != null ) {
+ for ( SqlResultSetMapping ann : anns ) {
+ QueryBinder.bindSqlResultsetMapping( ann, mappings, true );
+ }
+ }
+ }
+ }
+
+ public static void bindPackage(String packageName, ExtendedMappings mappings) {
+ XPackage pckg;
+ try {
+ pckg = mappings.getReflectionManager().packageForName( packageName );
+ }
+ catch ( ClassNotFoundException cnf ) {
+ log.warn( "Package not found or wo package-info.java: {}", packageName );
+ return;
+ }
+ if ( pckg.isAnnotationPresent( SequenceGenerator.class ) ) {
+ SequenceGenerator ann = pckg.getAnnotation( SequenceGenerator.class );
+ IdGenerator idGen = buildIdGenerator( ann, mappings );
+ mappings.addGenerator( idGen );
+ log.trace( "Add sequence generator with name: {}", idGen.getName() );
+ }
+ if ( pckg.isAnnotationPresent( TableGenerator.class ) ) {
+ TableGenerator ann = pckg.getAnnotation( TableGenerator.class );
+ IdGenerator idGen = buildIdGenerator( ann, mappings );
+ mappings.addGenerator( idGen );
+
+ }
+ bindGenericGenerators( pckg, mappings );
+ bindQueries( pckg, mappings );
+ bindFilterDefs( pckg, mappings );
+ bindTypeDefs( pckg, mappings );
+ bindFetchProfiles( pckg, mappings );
+ BinderHelper.bindAnyMetaDefs( pckg, mappings );
+ }
+
+ private static void bindGenericGenerators(XAnnotatedElement annotatedElement,
ExtendedMappings mappings) {
+ GenericGenerator defAnn = annotatedElement.getAnnotation( GenericGenerator.class );
+ GenericGenerators defsAnn = annotatedElement.getAnnotation( GenericGenerators.class );
+ if ( defAnn != null ) {
+ bindGenericGenerator( defAnn, mappings );
+ }
+ if ( defsAnn != null ) {
+ for ( GenericGenerator def : defsAnn.value() ) {
+ bindGenericGenerator( def, mappings );
+ }
+ }
+ }
+
+ private static void bindGenericGenerator(GenericGenerator def, ExtendedMappings
mappings) {
+ IdGenerator idGen = buildIdGenerator( def, mappings );
+ mappings.addGenerator( idGen );
+ }
+
+ private static void bindQueries(XAnnotatedElement annotatedElement, ExtendedMappings
mappings) {
+ {
+ SqlResultSetMapping ann = annotatedElement.getAnnotation( SqlResultSetMapping.class
);
+ QueryBinder.bindSqlResultsetMapping( ann, mappings, false );
+ }
+ {
+ SqlResultSetMappings ann = annotatedElement.getAnnotation( SqlResultSetMappings.class
);
+ if ( ann != null ) {
+ for ( SqlResultSetMapping current : ann.value() ) {
+ QueryBinder.bindSqlResultsetMapping( current, mappings, false );
+ }
+ }
+ }
+ {
+ NamedQuery ann = annotatedElement.getAnnotation( NamedQuery.class );
+ QueryBinder.bindQuery( ann, mappings, false );
+ }
+ {
+ org.hibernate.annotations.NamedQuery ann = annotatedElement.getAnnotation(
+ org.hibernate.annotations.NamedQuery.class
+ );
+ QueryBinder.bindQuery( ann, mappings );
+ }
+ {
+ NamedQueries ann = annotatedElement.getAnnotation( NamedQueries.class );
+ QueryBinder.bindQueries( ann, mappings, false );
+ }
+ {
+ org.hibernate.annotations.NamedQueries ann = annotatedElement.getAnnotation(
+ org.hibernate.annotations.NamedQueries.class
+ );
+ QueryBinder.bindQueries( ann, mappings );
+ }
+ {
+ NamedNativeQuery ann = annotatedElement.getAnnotation( NamedNativeQuery.class );
+ QueryBinder.bindNativeQuery( ann, mappings, false );
+ }
+ {
+ org.hibernate.annotations.NamedNativeQuery ann = annotatedElement.getAnnotation(
+ org.hibernate.annotations.NamedNativeQuery.class
+ );
+ QueryBinder.bindNativeQuery( ann, mappings );
+ }
+ {
+ NamedNativeQueries ann = annotatedElement.getAnnotation( NamedNativeQueries.class );
+ QueryBinder.bindNativeQueries( ann, mappings, false );
+ }
+ {
+ org.hibernate.annotations.NamedNativeQueries ann = annotatedElement.getAnnotation(
+ org.hibernate.annotations.NamedNativeQueries.class
+ );
+ QueryBinder.bindNativeQueries( ann, mappings );
+ }
+ }
+
+ private static IdGenerator buildIdGenerator(java.lang.annotation.Annotation ann,
ExtendedMappings mappings) {
+ IdGenerator idGen = new IdGenerator();
+ if ( mappings.getSchemaName() != null ) {
+ idGen.addParam( PersistentIdentifierGenerator.SCHEMA, mappings.getSchemaName() );
+ }
+ if ( mappings.getCatalogName() != null ) {
+ idGen.addParam( PersistentIdentifierGenerator.CATALOG, mappings.getCatalogName() );
+ }
+ final boolean useNewGeneratorMappings = mappings.useNewGeneratorMappings();
+ if ( ann == null ) {
+ idGen = null;
+ }
+ else if ( ann instanceof TableGenerator ) {
+ TableGenerator tabGen = ( TableGenerator ) ann;
+ idGen.setName( tabGen.name() );
+ if ( useNewGeneratorMappings ) {
+ idGen.setIdentifierGeneratorStrategy(
org.hibernate.id.enhanced.TableGenerator.class.getName() );
+ idGen.addParam(
org.hibernate.id.enhanced.TableGenerator.CONFIG_PREFER_SEGMENT_PER_ENTITY,
"true" );
+
+ if ( !BinderHelper.isDefault( tabGen.catalog() ) ) {
+ idGen.addParam( org.hibernate.id.enhanced.TableGenerator.CATALOG, tabGen.catalog()
);
+ }
+ if ( !BinderHelper.isDefault( tabGen.schema() ) ) {
+ idGen.addParam( org.hibernate.id.enhanced.TableGenerator.SCHEMA, tabGen.schema() );
+ }
+ if ( !BinderHelper.isDefault( tabGen.table() ) ) {
+ idGen.addParam( org.hibernate.id.enhanced.TableGenerator.TABLE_PARAM, tabGen.table()
);
+ }
+ if ( !BinderHelper.isDefault( tabGen.pkColumnName() ) ) {
+ idGen.addParam(
+ org.hibernate.id.enhanced.TableGenerator.SEGMENT_COLUMN_PARAM,
tabGen.pkColumnName()
+ );
+ }
+ if ( !BinderHelper.isDefault( tabGen.pkColumnValue() ) ) {
+ idGen.addParam(
+ org.hibernate.id.enhanced.TableGenerator.SEGMENT_VALUE_PARAM,
tabGen.pkColumnValue()
+ );
+ }
+ if ( !BinderHelper.isDefault( tabGen.valueColumnName() ) ) {
+ idGen.addParam(
+ org.hibernate.id.enhanced.TableGenerator.VALUE_COLUMN_PARAM,
tabGen.valueColumnName()
+ );
+ }
+ idGen.addParam(
+ org.hibernate.id.enhanced.TableGenerator.INCREMENT_PARAM,
+ String.valueOf( tabGen.allocationSize() )
+ );
+ // See comment on HHH-4884 wrt initialValue. Basically initialValue is really the
stated value + 1
+ idGen.addParam(
+ org.hibernate.id.enhanced.TableGenerator.INITIAL_PARAM,
+ String.valueOf( tabGen.initialValue() + 1 )
+ );
+ if ( tabGen.uniqueConstraints() != null && tabGen.uniqueConstraints().length
> 0 ) {
+ log.warn( "Ignoring unique constraints specified on table generator [{}]",
tabGen.name() );
+ }
+ }
+ else {
+ idGen.setIdentifierGeneratorStrategy( MultipleHiLoPerTableGenerator.class.getName()
);
+
+ if ( !BinderHelper.isDefault( tabGen.table() ) ) {
+ idGen.addParam( MultipleHiLoPerTableGenerator.ID_TABLE, tabGen.table() );
+ }
+ if ( !BinderHelper.isDefault( tabGen.catalog() ) ) {
+ idGen.addParam( MultipleHiLoPerTableGenerator.CATALOG, tabGen.catalog() );
+ }
+ if ( !BinderHelper.isDefault( tabGen.schema() ) ) {
+ idGen.addParam( MultipleHiLoPerTableGenerator.SCHEMA, tabGen.schema() );
+ }
+ //FIXME implement uniqueconstrains
+ if ( tabGen.uniqueConstraints() != null && tabGen.uniqueConstraints().length
> 0 ) {
+ log.warn( "Ignoring unique constraints specified on table generator [{}]",
tabGen.name() );
+ }
+
+ if ( !BinderHelper.isDefault( tabGen.pkColumnName() ) ) {
+ idGen.addParam( MultipleHiLoPerTableGenerator.PK_COLUMN_NAME, tabGen.pkColumnName()
);
+ }
+ if ( !BinderHelper.isDefault( tabGen.valueColumnName() ) ) {
+ idGen.addParam( MultipleHiLoPerTableGenerator.VALUE_COLUMN_NAME,
tabGen.valueColumnName() );
+ }
+ if ( !BinderHelper.isDefault( tabGen.pkColumnValue() ) ) {
+ idGen.addParam( MultipleHiLoPerTableGenerator.PK_VALUE_NAME, tabGen.pkColumnValue()
);
+ }
+ idGen.addParam( TableHiLoGenerator.MAX_LO, String.valueOf( tabGen.allocationSize() -
1 ) );
+ }
+ log.trace( "Add table generator with name: {}", idGen.getName() );
+ }
+ else if ( ann instanceof SequenceGenerator ) {
+ SequenceGenerator seqGen = ( SequenceGenerator ) ann;
+ idGen.setName( seqGen.name() );
+ if ( useNewGeneratorMappings ) {
+ idGen.setIdentifierGeneratorStrategy( SequenceStyleGenerator.class.getName() );
+
+ if ( !BinderHelper.isDefault( seqGen.catalog() ) ) {
+ idGen.addParam( SequenceStyleGenerator.CATALOG, seqGen.catalog() );
+ }
+ if ( !BinderHelper.isDefault( seqGen.schema() ) ) {
+ idGen.addParam( SequenceStyleGenerator.SCHEMA, seqGen.schema() );
+ }
+ if ( !BinderHelper.isDefault( seqGen.sequenceName() ) ) {
+ idGen.addParam( SequenceStyleGenerator.SEQUENCE_PARAM, seqGen.sequenceName() );
+ }
+ idGen.addParam( SequenceStyleGenerator.INCREMENT_PARAM, String.valueOf(
seqGen.allocationSize() ) );
+ idGen.addParam( SequenceStyleGenerator.INITIAL_PARAM, String.valueOf(
seqGen.initialValue() ) );
+ }
+ else {
+ idGen.setIdentifierGeneratorStrategy( "seqhilo" );
+
+ if ( !BinderHelper.isDefault( seqGen.sequenceName() ) ) {
+ idGen.addParam( org.hibernate.id.SequenceGenerator.SEQUENCE, seqGen.sequenceName()
);
+ }
+ //FIXME: work on initialValue() through SequenceGenerator.PARAMETERS
+ // steve : or just use o.h.id.enhanced.SequenceStyleGenerator
+ if ( seqGen.initialValue() != 1 ) {
+ log.warn(
+ "Hibernate does not support SequenceGenerator.initialValue() unless
'{}' set",
+ AnnotationConfiguration.USE_NEW_ID_GENERATOR_MAPPINGS
+ );
+ }
+ idGen.addParam( SequenceHiLoGenerator.MAX_LO, String.valueOf( seqGen.allocationSize()
- 1 ) );
+ log.trace( "Add sequence generator with name: {}", idGen.getName() );
+ }
+ }
+ else if ( ann instanceof GenericGenerator ) {
+ GenericGenerator genGen = ( GenericGenerator ) ann;
+ idGen.setName( genGen.name() );
+ idGen.setIdentifierGeneratorStrategy( genGen.strategy() );
+ Parameter[] params = genGen.parameters();
+ for ( Parameter parameter : params ) {
+ idGen.addParam( parameter.name(), parameter.value() );
+ }
+ log.trace( "Add generic generator with name: {}", idGen.getName() );
+ }
+ else {
+ throw new AssertionFailure( "Unknown Generator annotation: " + ann );
+ }
+ return idGen;
+ }
+
+ /**
+ * Bind a class having JSR175 annotations. Subclasses <b>have to</b> be
bound after its parent class.
+ *
+ * @param clazzToProcess entity to bind as {@code XClass} instance
+ * @param inheritanceStatePerClass Meta data about the inheritance relationships for all
mapped classes
+ * @param mappings Mapping meta data
+ *
+ * @throws MappingException in case there is an configuration error
+ */
+ public static void bindClass(
+ XClass clazzToProcess, Map<XClass, InheritanceState> inheritanceStatePerClass,
ExtendedMappings mappings
+ ) throws MappingException {
+ //@Entity and @MappedSuperclass on the same class leads to a NPE down the road
+ if ( clazzToProcess.isAnnotationPresent( Entity.class )
+ && clazzToProcess.isAnnotationPresent( MappedSuperclass.class ) ) {
+ throw new AnnotationException( "An entity cannot be annotated with both @Entity
and @MappedSuperclass: "
+ + clazzToProcess.getName() );
+ }
+
+ //TODO: be more strict with secondarytable allowance (not for ids, not for secondary
table join columns etc)
+ InheritanceState inheritanceState = inheritanceStatePerClass.get( clazzToProcess );
+ AnnotatedClassType classType = mappings.getClassType( clazzToProcess );
+
+ //Queries declared in MappedSuperclass should be usable in Subclasses
+ if ( AnnotatedClassType.EMBEDDABLE_SUPERCLASS.equals( classType ) ) {
+ bindQueries( clazzToProcess, mappings );
+ bindTypeDefs( clazzToProcess, mappings );
+ bindFilterDefs( clazzToProcess, mappings );
+ }
+
+ if ( !isEntityClassType( clazzToProcess, classType ) ) {
+ return;
+ }
+
+ log.info( "Binding entity from annotated class: {}", clazzToProcess.getName()
);
+
+ PersistentClass superEntity = getSuperEntity(
+ clazzToProcess, inheritanceStatePerClass, mappings, inheritanceState
+ );
+
+ bindQueries( clazzToProcess, mappings );
+ bindFilterDefs( clazzToProcess, mappings );
+ bindTypeDefs( clazzToProcess, mappings );
+ bindFetchProfiles( clazzToProcess, mappings );
+ BinderHelper.bindAnyMetaDefs( clazzToProcess, mappings );
+
+ String schema = "";
+ String table = ""; //might be no @Table annotation on the annotated class
+ String catalog = "";
+ List<UniqueConstraintHolder> uniqueConstraints = new
ArrayList<UniqueConstraintHolder>();
+ if ( clazzToProcess.isAnnotationPresent( javax.persistence.Table.class ) ) {
+ javax.persistence.Table tabAnn = clazzToProcess.getAnnotation(
javax.persistence.Table.class );
+ table = tabAnn.name();
+ schema = tabAnn.schema();
+ catalog = tabAnn.catalog();
+ uniqueConstraints = TableBinder.buildUniqueConstraintHolders(
tabAnn.uniqueConstraints() );
+ }
+
+ Ejb3JoinColumn[] inheritanceJoinedColumns = makeInheritanceJoinColumns(
+ clazzToProcess, mappings, inheritanceState, superEntity
+ );
+ Ejb3DiscriminatorColumn discriminatorColumn = null;
+ String discrimValue = null;
+ if ( InheritanceType.SINGLE_TABLE.equals( inheritanceState.getType() ) ) {
+ javax.persistence.DiscriminatorColumn discAnn = clazzToProcess.getAnnotation(
+ javax.persistence.DiscriminatorColumn.class
+ );
+ DiscriminatorType discriminatorType = discAnn != null ?
+ discAnn.discriminatorType() :
+ DiscriminatorType.STRING;
+
+ org.hibernate.annotations.DiscriminatorFormula discFormulaAnn =
clazzToProcess.getAnnotation(
+ org.hibernate.annotations.DiscriminatorFormula.class
+ );
+ if ( !inheritanceState.hasParents() ) {
+ discriminatorColumn = Ejb3DiscriminatorColumn.buildDiscriminatorColumn(
+ discriminatorType, discAnn, discFormulaAnn, mappings
+ );
+ }
+ if ( discAnn != null && inheritanceState.hasParents() ) {
+ log.warn(
+ "Discriminator column has to be defined in the root entity, it will be ignored
in subclass: {}",
+ clazzToProcess.getName()
+ );
+ }
+
+ discrimValue = clazzToProcess.isAnnotationPresent( DiscriminatorValue.class ) ?
+ clazzToProcess.getAnnotation( DiscriminatorValue.class ).value() :
+ null;
+ }
+
+ PersistentClass persistentClass = makePersistentClass( inheritanceState, superEntity
);
+
+ Proxy proxyAnn = clazzToProcess.getAnnotation( Proxy.class );
+ BatchSize sizeAnn = clazzToProcess.getAnnotation( BatchSize.class );
+ Where whereAnn = clazzToProcess.getAnnotation( Where.class );
+ Entity entityAnn = clazzToProcess.getAnnotation( Entity.class );
+ org.hibernate.annotations.Entity hibEntityAnn = clazzToProcess.getAnnotation(
+ org.hibernate.annotations.Entity.class
+ );
+
+ Cache cacheAnn = determineCacheSettings( clazzToProcess, mappings );
+
+ EntityBinder entityBinder = new EntityBinder(
+ entityAnn, hibEntityAnn, clazzToProcess, persistentClass, mappings
+ );
+ entityBinder.setDiscriminatorValue( discrimValue );
+ entityBinder.setBatchSize( sizeAnn );
+ entityBinder.setProxy( proxyAnn );
+ entityBinder.setWhere( whereAnn );
+ entityBinder.setCache( cacheAnn );
+ entityBinder.setInheritanceState( inheritanceState );
+
+ //Filters are not allowed on subclasses
+ if ( !inheritanceState.hasParents() ) {
+ bindFilters( clazzToProcess, entityBinder, mappings );
+ }
+
+ entityBinder.bindEntity();
+
+ if ( inheritanceState.hasTable() ) {
+ Check checkAnn = clazzToProcess.getAnnotation( Check.class );
+ String constraints = checkAnn == null ?
+ null :
+ checkAnn.constraints();
+ entityBinder.bindTable(
+ schema, catalog, table, uniqueConstraints,
+ constraints, inheritanceState.hasDenormalizedTable() ?
+ superEntity.getTable() :
+ null
+ );
+ }
+ else {
+ if ( clazzToProcess.isAnnotationPresent( Table.class ) ) {
+ log.warn(
+ "Illegal use of @Table in a subclass of a SINGLE_TABLE hierarchy: " +
clazzToProcess
+ .getName()
+ );
+ }
+ }
+
+ PropertyHolder propertyHolder = PropertyHolderBuilder.buildPropertyHolder(
+ clazzToProcess,
+ persistentClass,
+ entityBinder, mappings, inheritanceStatePerClass
+ );
+
+ javax.persistence.SecondaryTable secTabAnn = clazzToProcess.getAnnotation(
+ javax.persistence.SecondaryTable.class
+ );
+ javax.persistence.SecondaryTables secTabsAnn = clazzToProcess.getAnnotation(
+ javax.persistence.SecondaryTables.class
+ );
+ entityBinder.firstLevelSecondaryTablesBinding( secTabAnn, secTabsAnn );
+
+ OnDelete onDeleteAnn = clazzToProcess.getAnnotation( OnDelete.class );
+ boolean onDeleteAppropriate = false;
+ if ( InheritanceType.JOINED.equals( inheritanceState.getType() ) &&
inheritanceState.hasParents() ) {
+ onDeleteAppropriate = true;
+ final JoinedSubclass jsc = ( JoinedSubclass ) persistentClass;
+ if ( persistentClass.getEntityPersisterClass() == null ) {
+ persistentClass.getRootClass().setEntityPersisterClass(
JoinedSubclassEntityPersister.class );
+ }
+ SimpleValue key = new DependantValue( mappings, jsc.getTable(), jsc.getIdentifier()
);
+ jsc.setKey( key );
+ ForeignKey fk = clazzToProcess.getAnnotation( ForeignKey.class );
+ if ( fk != null && !BinderHelper.isDefault( fk.name() ) ) {
+ key.setForeignKeyName( fk.name() );
+ }
+ if ( onDeleteAnn != null ) {
+ key.setCascadeDeleteEnabled( OnDeleteAction.CASCADE.equals( onDeleteAnn.action() )
);
+ }
+ else {
+ key.setCascadeDeleteEnabled( false );
+ }
+ //we are never in a second pass at that stage, so queue it
+ SecondPass sp = new JoinedSubclassFkSecondPass( jsc, inheritanceJoinedColumns, key,
mappings );
+ mappings.addSecondPass( sp );
+ mappings.addSecondPass( new CreateKeySecondPass( jsc ) );
+
+ }
+ else if ( InheritanceType.SINGLE_TABLE.equals( inheritanceState.getType() ) ) {
+ if ( inheritanceState.hasParents() ) {
+ if ( persistentClass.getEntityPersisterClass() == null ) {
+ persistentClass.getRootClass().setEntityPersisterClass(
SingleTableEntityPersister.class );
+ }
+ }
+ else {
+ if ( inheritanceState.hasSiblings() || !discriminatorColumn.isImplicit() ) {
+ //need a discriminator column
+ bindDiscriminatorToPersistentClass(
+ ( RootClass ) persistentClass,
+ discriminatorColumn,
+ entityBinder.getSecondaryTables(),
+ propertyHolder,
+ mappings
+ );
+ entityBinder.bindDiscriminatorValue();//bind it again since the type might have
changed
+ }
+ }
+ }
+ else if ( InheritanceType.TABLE_PER_CLASS.equals( inheritanceState.getType() ) ) {
+ if ( inheritanceState.hasParents() ) {
+ if ( persistentClass.getEntityPersisterClass() == null ) {
+ persistentClass.getRootClass().setEntityPersisterClass(
UnionSubclassEntityPersister.class );
+ }
+ }
+ }
+ if ( onDeleteAnn != null && !onDeleteAppropriate ) {
+ log.warn(
+ "Inapropriate use of @OnDelete on entity, annotation ignored: {}",
propertyHolder.getEntityName()
+ );
+ }
+
+ // try to find class level generators
+ HashMap<String, IdGenerator> classGenerators = buildLocalGenerators(
clazzToProcess, mappings );
+
+ // check properties
+ final InheritanceState.ElementsToProcess elementsToProcess =
inheritanceState.getElementsToProcess();
+ inheritanceState.postProcess( persistentClass, entityBinder );
+
+ final boolean subclassAndSingleTableStrategy = inheritanceState.getType() ==
InheritanceType.SINGLE_TABLE
+ && inheritanceState.hasParents();
+ Set<String> idPropertiesIfIdClass = new HashSet<String>();
+ boolean isIdClass = mapAsIdClass(
+ inheritanceStatePerClass,
+ inheritanceState,
+ persistentClass,
+ entityBinder,
+ propertyHolder,
+ elementsToProcess,
+ idPropertiesIfIdClass,
+ mappings
+ );
+
+ if ( !isIdClass ) {
+ entityBinder.setWrapIdsInEmbeddedComponents( elementsToProcess.getIdPropertyCount()
> 1 );
+ }
+
+ processIdPropertiesIfNotAlready(
+ inheritanceStatePerClass,
+ mappings,
+ persistentClass,
+ entityBinder,
+ propertyHolder,
+ classGenerators,
+ elementsToProcess,
+ subclassAndSingleTableStrategy,
+ idPropertiesIfIdClass
+ );
+
+ if ( !inheritanceState.hasParents() ) {
+ final RootClass rootClass = ( RootClass ) persistentClass;
+ mappings.addSecondPass( new CreateKeySecondPass( rootClass ) );
+ }
+ else {
+ superEntity.addSubclass( ( Subclass ) persistentClass );
+ }
+
+ mappings.addClass( persistentClass );
+
+ //Process secondary tables and complementary definitions (ie o.h.a.Table)
+ mappings.addSecondPass( new SecondaryTableSecondPass( entityBinder, propertyHolder,
clazzToProcess ) );
+
+ //add process complementary Table definition (index & all)
+ entityBinder.processComplementaryTableDefinitions( clazzToProcess.getAnnotation(
org.hibernate.annotations.Table.class ) );
+ entityBinder.processComplementaryTableDefinitions( clazzToProcess.getAnnotation(
org.hibernate.annotations.Tables.class ) );
+
+ }
+
+ private static void processIdPropertiesIfNotAlready(Map<XClass, InheritanceState>
inheritanceStatePerClass, ExtendedMappings mappings, PersistentClass persistentClass,
EntityBinder entityBinder, PropertyHolder propertyHolder, HashMap<String,
IdGenerator> classGenerators, InheritanceState.ElementsToProcess elementsToProcess,
boolean subclassAndSingleTableStrategy, Set<String> idPropertiesIfIdClass) {
+ Set<String> missingIdProperties = new HashSet<String>(
idPropertiesIfIdClass );
+ for ( PropertyData propertyAnnotatedElement : elementsToProcess.getElements() ) {
+ String propertyName = propertyAnnotatedElement.getPropertyName();
+ if ( !idPropertiesIfIdClass.contains( propertyName ) ) {
+ processElementAnnotations(
+ propertyHolder,
+ subclassAndSingleTableStrategy ?
+ Nullability.FORCED_NULL :
+ Nullability.NO_CONSTRAINT,
+ propertyAnnotatedElement, classGenerators, entityBinder,
+ false, false, false, mappings, inheritanceStatePerClass
+ );
+ }
+ else {
+ missingIdProperties.remove( propertyName );
+ }
+ }
+
+ if ( missingIdProperties.size() != 0 ) {
+ StringBuilder missings = new StringBuilder();
+ for ( String property : missingIdProperties ) {
+ missings.append( property ).append( ", " );
+ }
+ throw new AnnotationException(
+ "Unable to find properties ("
+ + missings.substring( 0, missings.length() - 2 )
+ + ") in entity annotated with @IdClass:" +
persistentClass.getEntityName()
+ );
+ }
+ }
+
+ private static boolean mapAsIdClass(Map<XClass, InheritanceState>
inheritanceStatePerClass, InheritanceState inheritanceState, PersistentClass
persistentClass, EntityBinder entityBinder, PropertyHolder propertyHolder,
InheritanceState.ElementsToProcess elementsToProcess, Set<String>
idPropertiesIfIdClass, ExtendedMappings mappings) {
+ /*
+ * We are looking for @IdClass
+ * In general we map the id class as identifier using the mapping metadata of the main
entity's properties
+ * and we create an identifier mapper containing the id properties of the main entity
+ *
+ * In JPA 2, there is a shortcut if the id class is the Pk of the associated class
pointed to by the id
+ * it ought to be treated as an embedded and not a real IdClass (at least in the
Hibernate's internal way
+ */
+ XClass classWithIdClass = inheritanceState.getClassWithIdClass( false );
+ if ( classWithIdClass != null ) {
+ IdClass idClass = classWithIdClass.getAnnotation( IdClass.class );
+ XClass compositeClass = mappings.getReflectionManager().toXClass( idClass.value() );
+ PropertyData inferredData = new PropertyPreloadedData(
+ entityBinder.getPropertyAccessType(), "id", compositeClass
+ );
+ PropertyData baseInferredData = new PropertyPreloadedData(
+ entityBinder.getPropertyAccessType(), "id", classWithIdClass
+ );
+ AccessType propertyAccessor = entityBinder.getPropertyAccessor( compositeClass );
+ //In JPA 2, there is a shortcut if the IdClass is the Pk of the associated class
pointed to by the id
+ //it ought to be treated as an embedded and not a real IdClass (at least in the
Hibernate's internal way
+ final boolean isFakeIdClass = isIdClassPkOfTheAssociatedEntity(
+ elementsToProcess,
+ compositeClass,
+ inferredData,
+ baseInferredData,
+ propertyAccessor,
+ inheritanceStatePerClass,
+ mappings
+ );
+
+ if ( isFakeIdClass ) {
+ return false;
+ }
+
+ boolean isComponent = true;
+ String generatorType = "assigned";
+ String generator = BinderHelper.ANNOTATION_STRING_DEFAULT;
+
+ boolean ignoreIdAnnotations = entityBinder.isIgnoreIdAnnotations();
+ entityBinder.setIgnoreIdAnnotations( true );
+ propertyHolder.setInIdClass( true );
+ bindIdClass(
+ generatorType,
+ generator,
+ inferredData,
+ baseInferredData,
+ null,
+ propertyHolder,
+ isComponent,
+ propertyAccessor,
+ entityBinder,
+ true,
+ false,
+ mappings,
+ inheritanceStatePerClass
+ );
+ propertyHolder.setInIdClass( null );
+ inferredData = new PropertyPreloadedData(
+ propertyAccessor, "_identifierMapper", compositeClass
+ );
+ Component mapper = fillComponent(
+ propertyHolder,
+ inferredData,
+ baseInferredData,
+ propertyAccessor,
+ false,
+ entityBinder,
+ true,
+ true,
+ false,
+ mappings,
+ inheritanceStatePerClass
+ );
+ entityBinder.setIgnoreIdAnnotations( ignoreIdAnnotations );
+ persistentClass.setIdentifierMapper( mapper );
+
+ //If id definition is on a mapped superclass, update the mapping
+ final org.hibernate.mapping.MappedSuperclass superclass =
+ BinderHelper.getMappedSuperclassOrNull(
+ inferredData.getDeclaringClass(),
+ inheritanceStatePerClass,
+ mappings
+ );
+ if ( superclass != null ) {
+ superclass.setDeclaredIdentifierMapper( mapper );
+ }
+ else {
+ //we are for sure on the entity
+ persistentClass.setDeclaredIdentifierMapper( mapper );
+ }
+
+ Property property = new Property();
+ property.setName( "_identifierMapper" );
+ property.setNodeName( "id" );
+ property.setUpdateable( false );
+ property.setInsertable( false );
+ property.setValue( mapper );
+ property.setPropertyAccessorName( "embedded" );
+ persistentClass.addProperty( property );
+ entityBinder.setIgnoreIdAnnotations( true );
+
+ Iterator properties = mapper.getPropertyIterator();
+ while ( properties.hasNext() ) {
+ idPropertiesIfIdClass.add( ( ( Property ) properties.next() ).getName() );
+ }
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ private static boolean isIdClassPkOfTheAssociatedEntity(
+ InheritanceState.ElementsToProcess elementsToProcess,
+ XClass compositeClass,
+ PropertyData inferredData,
+ PropertyData baseInferredData,
+ AccessType propertyAccessor,
+ Map<XClass, InheritanceState> inheritanceStatePerClass,
+ ExtendedMappings mappings) {
+ if ( elementsToProcess.getIdPropertyCount() == 1 ) {
+ final PropertyData idPropertyOnBaseClass = getUniqueIdPropertyFromBaseClass(
+ inferredData, baseInferredData, propertyAccessor, mappings
+ );
+ final InheritanceState state = inheritanceStatePerClass.get(
idPropertyOnBaseClass.getClassOrElement() );
+ if ( state == null ) {
+ return false; //while it is likely a user error, let's consider it is something
that might happen
+ }
+ final XClass associatedClassWithIdClass = state.getClassWithIdClass( true );
+ if ( associatedClassWithIdClass == null ) {
+ //we cannot know for sure here unless we try and find the @EmbeddedId
+ //Let's not do this thorough checking but do some extra validation
+ final XProperty property = idPropertyOnBaseClass.getProperty();
+ return property.isAnnotationPresent( ManyToOne.class )
+ || property.isAnnotationPresent( OneToOne.class );
+
+ }
+ else {
+ final XClass idClass = mappings.getReflectionManager().toXClass(
+ associatedClassWithIdClass.getAnnotation( IdClass.class ).value()
+ );
+ return idClass.equals( compositeClass );
+ }
+ }
+ else {
+ return false;
+ }
+ }
+
+ private static Cache determineCacheSettings(XClass clazzToProcess, ExtendedMappings
mappings) {
+ Cache cacheAnn = clazzToProcess.getAnnotation( Cache.class );
+ if ( cacheAnn != null ) {
+ return cacheAnn;
+ }
+
+ Cacheable cacheableAnn = clazzToProcess.getAnnotation( Cacheable.class );
+ SharedCacheMode mode = determineSharedCacheMode( mappings );
+ switch ( mode ) {
+ case ALL: {
+ cacheAnn = buildCacheMock( clazzToProcess.getName(), mappings );
+ break;
+ }
+ case ENABLE_SELECTIVE: {
+ if ( cacheableAnn != null && cacheableAnn.value() ) {
+ cacheAnn = buildCacheMock( clazzToProcess.getName(), mappings );
+ }
+ break;
+ }
+ case DISABLE_SELECTIVE: {
+ if ( cacheableAnn == null || cacheableAnn.value() ) {
+ cacheAnn = buildCacheMock( clazzToProcess.getName(), mappings );
+ }
+ break;
+ }
+ default: {
+ // treat both NONE and UNSPECIFIED the same
+ break;
+ }
+ }
+ return cacheAnn;
+ }
+
+ private static SharedCacheMode determineSharedCacheMode(ExtendedMappings mappings) {
+ SharedCacheMode mode;
+ final Object value = mappings.getConfigurationProperties().get(
"javax.persistence.sharedCache.mode" );
+ if ( value == null ) {
+ log.debug( "no value specified for 'javax.persistence.sharedCache.mode';
using UNSPECIFIED" );
+ mode = SharedCacheMode.UNSPECIFIED;
+ }
+ else {
+ if ( SharedCacheMode.class.isInstance( value ) ) {
+ mode = ( SharedCacheMode ) value;
+ }
+ else {
+ try {
+ mode = SharedCacheMode.valueOf( value.toString() );
+ }
+ catch ( Exception e ) {
+ log.debug(
+ "Unable to resolve given mode name [" + value.toString()
+ + "]; using UNSPECIFIED : " + e.toString()
+ );
+ mode = SharedCacheMode.UNSPECIFIED;
+ }
+ }
+ }
+ return mode;
+ }
+
+ private static Cache buildCacheMock(String region, ExtendedMappings mappings) {
+ return new LocalCacheAnnotationImpl( region, determineCacheConcurrencyStrategy(
mappings ) );
+ }
+
+ private static CacheConcurrencyStrategy DEFAULT_CACHE_CONCURRENCY_STRATEGY;
+
+ static void prepareDefaultCacheConcurrencyStrategy(Properties properties) {
+ if ( DEFAULT_CACHE_CONCURRENCY_STRATEGY != null ) {
+ log.trace( "Default cache concurrency strategy already defined" );
+ return;
+ }
+
+ if ( !properties.containsKey(
AnnotationConfiguration.DEFAULT_CACHE_CONCURRENCY_STRATEGY ) ) {
+ log.trace( "Given properties did not contain any default cache concurrency
strategy setting" );
+ return;
+ }
+
+ final String strategyName = properties.getProperty(
AnnotationConfiguration.DEFAULT_CACHE_CONCURRENCY_STRATEGY );
+ log.trace( "Discovered default cache concurrency strategy via config [" +
strategyName + "]" );
+ CacheConcurrencyStrategy strategy = CacheConcurrencyStrategy.parse( strategyName );
+ if ( strategy == null ) {
+ log.trace( "Discovered default cache concurrency strategy specified nothing"
);
+ return;
+ }
+
+ log.debug( "Setting default cache concurrency strategy via config [" +
strategy.name() + "]" );
+ DEFAULT_CACHE_CONCURRENCY_STRATEGY = strategy;
+ }
+
+ private static CacheConcurrencyStrategy
determineCacheConcurrencyStrategy(ExtendedMappings mappings) {
+ if ( DEFAULT_CACHE_CONCURRENCY_STRATEGY == null ) {
+ final RegionFactory cacheRegionFactory = SettingsFactory.createRegionFactory(
+ mappings.getConfigurationProperties(), true
+ );
+ DEFAULT_CACHE_CONCURRENCY_STRATEGY = CacheConcurrencyStrategy.fromAccessType(
cacheRegionFactory.getDefaultAccessType() );
+ }
+ return DEFAULT_CACHE_CONCURRENCY_STRATEGY;
+ }
+
+ @SuppressWarnings({ "ClassExplicitlyAnnotation" })
+ private static class LocalCacheAnnotationImpl implements Cache {
+ private final String region;
+ private final CacheConcurrencyStrategy usage;
+
+ private LocalCacheAnnotationImpl(String region, CacheConcurrencyStrategy usage) {
+ this.region = region;
+ this.usage = usage;
+ }
+
+ public CacheConcurrencyStrategy usage() {
+ return usage;
+ }
+
+ public String region() {
+ return region;
+ }
+
+ public String include() {
+ return "all";
+ }
+
+ public Class<? extends Annotation> annotationType() {
+ return Cache.class;
+ }
+ }
+
+ private static PersistentClass makePersistentClass(InheritanceState inheritanceState,
PersistentClass superEntity) {
+ //we now know what kind of persistent entity it is
+ PersistentClass persistentClass;
+ //create persistent class
+ if ( !inheritanceState.hasParents() ) {
+ persistentClass = new RootClass();
+ }
+ else if ( InheritanceType.SINGLE_TABLE.equals( inheritanceState.getType() ) ) {
+ persistentClass = new SingleTableSubclass( superEntity );
+ }
+ else if ( InheritanceType.JOINED.equals( inheritanceState.getType() ) ) {
+ persistentClass = new JoinedSubclass( superEntity );
+ }
+ else if ( InheritanceType.TABLE_PER_CLASS.equals( inheritanceState.getType() ) ) {
+ persistentClass = new UnionSubclass( superEntity );
+ }
+ else {
+ throw new AssertionFailure( "Unknown inheritance type: " +
inheritanceState.getType() );
+ }
+ return persistentClass;
+ }
+
+ private static Ejb3JoinColumn[] makeInheritanceJoinColumns(XClass clazzToProcess,
ExtendedMappings mappings, InheritanceState inheritanceState, PersistentClass superEntity)
{
+ Ejb3JoinColumn[] inheritanceJoinedColumns = null;
+ final boolean hasJoinedColumns = inheritanceState.hasParents()
+ && InheritanceType.JOINED.equals( inheritanceState.getType() );
+ if ( hasJoinedColumns ) {
+ //@Inheritance(JOINED) subclass need to link back to the super entity
+ PrimaryKeyJoinColumns jcsAnn = clazzToProcess.getAnnotation(
PrimaryKeyJoinColumns.class );
+ boolean explicitInheritanceJoinedColumns = jcsAnn != null &&
jcsAnn.value().length != 0;
+ if ( explicitInheritanceJoinedColumns ) {
+ int nbrOfInhJoinedColumns = jcsAnn.value().length;
+ PrimaryKeyJoinColumn jcAnn;
+ inheritanceJoinedColumns = new Ejb3JoinColumn[nbrOfInhJoinedColumns];
+ for ( int colIndex = 0; colIndex < nbrOfInhJoinedColumns; colIndex++ ) {
+ jcAnn = jcsAnn.value()[colIndex];
+ inheritanceJoinedColumns[colIndex] = Ejb3JoinColumn.buildJoinColumn(
+ jcAnn, null, superEntity.getIdentifier(),
+ ( Map<String, Join> ) null, ( PropertyHolder ) null, mappings
+ );
+ }
+ }
+ else {
+ PrimaryKeyJoinColumn jcAnn = clazzToProcess.getAnnotation( PrimaryKeyJoinColumn.class
);
+ inheritanceJoinedColumns = new Ejb3JoinColumn[1];
+ inheritanceJoinedColumns[0] = Ejb3JoinColumn.buildJoinColumn(
+ jcAnn, null, superEntity.getIdentifier(),
+ ( Map<String, Join> ) null, ( PropertyHolder ) null, mappings
+ );
+ }
+ log.trace( "Subclass joined column(s) created" );
+ }
+ else {
+ if ( clazzToProcess.isAnnotationPresent( PrimaryKeyJoinColumns.class )
+ || clazzToProcess.isAnnotationPresent( PrimaryKeyJoinColumn.class ) ) {
+ log.warn( "Root entity should not hold an PrimaryKeyJoinColum(s), will be
ignored" );
+ }
+ }
+ return inheritanceJoinedColumns;
+ }
+
+ private static PersistentClass getSuperEntity(XClass clazzToProcess, Map<XClass,
InheritanceState> inheritanceStatePerClass, ExtendedMappings mappings, InheritanceState
inheritanceState) {
+ InheritanceState superEntityState = InheritanceState.getInheritanceStateOfSuperEntity(
+ clazzToProcess, inheritanceStatePerClass
+ );
+ PersistentClass superEntity = superEntityState != null ?
+ mappings.getClass(
+ superEntityState.getClazz().getName()
+ ) :
+ null;
+ if ( superEntity == null ) {
+ //check if superclass is not a potential persistent class
+ if ( inheritanceState.hasParents() ) {
+ throw new AssertionFailure(
+ "Subclass has to be binded after it's mother class: "
+ + superEntityState.getClazz().getName()
+ );
+ }
+ }
+ return superEntity;
+ }
+
+ private static boolean isEntityClassType(XClass clazzToProcess, AnnotatedClassType
classType) {
+ if ( AnnotatedClassType.EMBEDDABLE_SUPERCLASS.equals( classType ) //will be processed
by their subentities
+ || AnnotatedClassType.NONE.equals( classType ) //to be ignored
+ || AnnotatedClassType.EMBEDDABLE.equals( classType ) //allow embeddable element
declaration
+ ) {
+ if ( AnnotatedClassType.NONE.equals( classType )
+ && clazzToProcess.isAnnotationPresent(
org.hibernate.annotations.Entity.class ) ) {
+ log.warn(
+ "Class annotated @org.hibernate.annotations.Entity but not
javax.persistence.Entity "
+ + "(most likely a user error): {}", clazzToProcess.getName()
+ );
+ }
+ return false;
+ }
+
+ if ( !classType.equals( AnnotatedClassType.ENTITY ) ) {
+ throw new AnnotationException(
+ "Annotated class should have a @javax.persistence.Entity,
@javax.persistence.Embeddable or @javax.persistence.EmbeddedSuperclass annotation: "
+ clazzToProcess
+ .getName()
+ );
+ }
+
+ return true;
+ }
+
+ /*
+ * Process the filters defined on the given class, as well as all filters defined
+ * on the MappedSuperclass(s) in the inheritance hierarchy
+ */
+
+ private static void bindFilters(XClass annotatedClass, EntityBinder entityBinder,
+ ExtendedMappings mappings) {
+
+ bindFilters( annotatedClass, entityBinder );
+
+ XClass classToProcess = annotatedClass.getSuperclass();
+ while ( classToProcess != null ) {
+ AnnotatedClassType classType = mappings.getClassType( classToProcess );
+ if ( AnnotatedClassType.EMBEDDABLE_SUPERCLASS.equals( classType ) ) {
+ bindFilters( classToProcess, entityBinder );
+ }
+ classToProcess = classToProcess.getSuperclass();
+ }
+
+ }
+
+ private static void bindFilters(XAnnotatedElement annotatedElement, EntityBinder
entityBinder) {
+
+ Filters filtersAnn = annotatedElement.getAnnotation( Filters.class );
+ if ( filtersAnn != null ) {
+ for ( Filter filter : filtersAnn.value() ) {
+ entityBinder.addFilter( filter.name(), filter.condition() );
+ }
+ }
+
+ Filter filterAnn = annotatedElement.getAnnotation( Filter.class );
+ if ( filterAnn != null ) {
+ entityBinder.addFilter( filterAnn.name(), filterAnn.condition() );
+ }
+ }
+
+ private static void bindFilterDefs(XAnnotatedElement annotatedElement, ExtendedMappings
mappings) {
+ FilterDef defAnn = annotatedElement.getAnnotation( FilterDef.class );
+ FilterDefs defsAnn = annotatedElement.getAnnotation( FilterDefs.class );
+ if ( defAnn != null ) {
+ bindFilterDef( defAnn, mappings );
+ }
+ if ( defsAnn != null ) {
+ for ( FilterDef def : defsAnn.value() ) {
+ bindFilterDef( def, mappings );
+ }
+ }
+ }
+
+ private static void bindFilterDef(FilterDef defAnn, ExtendedMappings mappings) {
+ Map<String, org.hibernate.type.Type> params = new HashMap<String,
org.hibernate.type.Type>();
+ for ( ParamDef param : defAnn.parameters() ) {
+ params.put( param.name(), mappings.getTypeResolver().heuristicType( param.type() ) );
+ }
+ FilterDefinition def = new FilterDefinition( defAnn.name(), defAnn.defaultCondition(),
params );
+ log.info( "Binding filter definition: {}", def.getFilterName() );
+ mappings.addFilterDefinition( def );
+ }
+
+ private static void bindTypeDefs(XAnnotatedElement annotatedElement, ExtendedMappings
mappings) {
+ TypeDef defAnn = annotatedElement.getAnnotation( TypeDef.class );
+ TypeDefs defsAnn = annotatedElement.getAnnotation( TypeDefs.class );
+ if ( defAnn != null ) {
+ bindTypeDef( defAnn, mappings );
+ }
+ if ( defsAnn != null ) {
+ for ( TypeDef def : defsAnn.value() ) {
+ bindTypeDef( def, mappings );
+ }
+ }
+ }
+
+ private static void bindFetchProfiles(XAnnotatedElement annotatedElement,
ExtendedMappings mappings) {
+ FetchProfile fetchProfileAnnotation = annotatedElement.getAnnotation(
FetchProfile.class );
+ FetchProfiles fetchProfileAnnotations = annotatedElement.getAnnotation(
FetchProfiles.class );
+ if ( fetchProfileAnnotation != null ) {
+ bindFetchProfile( fetchProfileAnnotation, mappings );
+ }
+ if ( fetchProfileAnnotations != null ) {
+ for ( FetchProfile profile : fetchProfileAnnotations.value() ) {
+ bindFetchProfile( profile, mappings );
+ }
+ }
+ }
+
+ private static void bindFetchProfile(FetchProfile fetchProfileAnnotation,
ExtendedMappings mappings) {
+ for ( FetchProfile.FetchOverride fetch : fetchProfileAnnotation.fetchOverrides() ) {
+ org.hibernate.annotations.FetchMode mode = fetch.mode();
+ if ( !mode.equals( org.hibernate.annotations.FetchMode.JOIN ) ) {
+ throw new MappingException( "Only FetchMode.JOIN is currently supported"
);
+ }
+
+ SecondPass sp = new VerifyFetchProfileReferenceSecondPass(
fetchProfileAnnotation.name(), fetch, mappings );
+ mappings.addSecondPass( sp );
+ }
+ }
+
+ private static void bindTypeDef(TypeDef defAnn, ExtendedMappings mappings) {
+ Properties params = new Properties();
+ for ( Parameter param : defAnn.parameters() ) {
+ params.setProperty( param.name(), param.value() );
+ }
+
+ if ( BinderHelper.isDefault( defAnn.name() ) && defAnn.defaultForType().equals(
void.class ) ) {
+ throw new AnnotationException(
+ "Either name or defaultForType (or both) attribute should be set in TypeDef
having typeClass " +
+ defAnn.typeClass().getName()
+ );
+ }
+
+ if ( !BinderHelper.isDefault( defAnn.name() ) ) {
+ log.info( "Binding type definition: {}", defAnn.name() );
+ mappings.addTypeDef( defAnn.name(), defAnn.typeClass().getName(), params );
+ }
+ if ( !defAnn.defaultForType().equals( void.class ) ) {
+ log.info( "Binding type definition: {}", defAnn.defaultForType().getName()
);
+ mappings.addTypeDef( defAnn.defaultForType().getName(), defAnn.typeClass().getName(),
params );
+ }
+
+ }
+
+
+ private static void bindDiscriminatorToPersistentClass(
+ RootClass rootClass,
+ Ejb3DiscriminatorColumn discriminatorColumn,
+ Map<String, Join> secondaryTables,
+ PropertyHolder propertyHolder,
+ ExtendedMappings mappings) {
+ if ( rootClass.getDiscriminator() == null ) {
+ if ( discriminatorColumn == null ) {
+ throw new AssertionFailure( "discriminator column should have been built"
);
+ }
+ discriminatorColumn.setJoins( secondaryTables );
+ discriminatorColumn.setPropertyHolder( propertyHolder );
+ SimpleValue discrim = new SimpleValue( mappings, rootClass.getTable() );
+ rootClass.setDiscriminator( discrim );
+ discriminatorColumn.linkWithValue( discrim );
+ discrim.setTypeName( discriminatorColumn.getDiscriminatorTypeName() );
+ rootClass.setPolymorphic( true );
+ log.trace( "Setting discriminator for entity {}", rootClass.getEntityName()
);
+ }
+ }
+
+ /**
+ * @param elements List of {@code ProperyData} instances
+ * @param defaultAccessType The default value access strategy which has to be used in
case no explicit local access
+ * strategy is used
+ * @param propertyContainer Metadata about a class and its properties
+ * @param mappings Mapping meta data
+ *
+ * @return the number of id properties found while iterating the elements of {@code
annotatedClass} using
+ * the determined access strategy, {@code false} otherwise.
+ */
+ static int addElementsOfClass(
+ List<PropertyData> elements, AccessType defaultAccessType, PropertyContainer
propertyContainer, ExtendedMappings mappings
+ ) {
+ int idPropertyCounter = 0;
+ AccessType accessType = defaultAccessType;
+
+ if ( propertyContainer.hasExplicitAccessStrategy() ) {
+ accessType = propertyContainer.getExplicitAccessStrategy();
+ }
+
+ Collection<XProperty> properties = propertyContainer.getProperties( accessType
);
+ for ( XProperty p : properties ) {
+ final int currentIdPropertyCounter = addProperty(
+ propertyContainer, p, elements, accessType.getType(), mappings
+ );
+ idPropertyCounter += currentIdPropertyCounter;
+ }
+ return idPropertyCounter;
+ }
+
+ private static int addProperty(
+ PropertyContainer propertyContainer, XProperty property, List<PropertyData>
annElts,
+ String propertyAccessor, ExtendedMappings mappings
+ ) {
+ final XClass declaringClass = propertyContainer.getDeclaringClass();
+ final XClass entity = propertyContainer.getEntityAtStake();
+ int idPropertyCounter = 0;
+ PropertyData propertyAnnotatedElement = new PropertyInferredData(
+ declaringClass, property, propertyAccessor,
+ mappings.getReflectionManager()
+ );
+
+ /*
+ * put element annotated by @Id in front
+ * since it has to be parsed before any association by Hibernate
+ */
+ final XAnnotatedElement element = propertyAnnotatedElement.getProperty();
+ if ( element.isAnnotationPresent( Id.class ) || element.isAnnotationPresent(
EmbeddedId.class ) ) {
+ annElts.add( 0, propertyAnnotatedElement );
+ if ( element.isAnnotationPresent( ManyToOne.class ) || element.isAnnotationPresent(
OneToOne.class ) ) {
+ mappings.addToOneAndIdProperty( entity, propertyAnnotatedElement );
+ }
+ idPropertyCounter++;
+ }
+ else {
+ annElts.add( propertyAnnotatedElement );
+ }
+ if ( element.isAnnotationPresent( MapsId.class ) ) {
+ mappings.addPropertyAnnotatedWithMapsId( entity, propertyAnnotatedElement );
+ }
+
+ return idPropertyCounter;
+ }
+
+ /*
+ * Process annotation of a particular property
+ */
+
+ private static void processElementAnnotations(
+ PropertyHolder propertyHolder, Nullability nullability,
+ PropertyData inferredData, HashMap<String, IdGenerator> classGenerators,
+ EntityBinder entityBinder, boolean isIdentifierMapper,
+ boolean isComponentEmbedded, boolean inSecondPass, ExtendedMappings mappings,
+ Map<XClass, InheritanceState> inheritanceStatePerClass
+ ) throws MappingException {
+ /**
+ * inSecondPass can only be used to apply right away the second pass of a
composite-element
+ * Because it's a value type, there is no bidirectional association, hence second
pass
+ * ordering does not matter
+ */
+
+ log.trace(
+ "Processing annotations of {}.{}", propertyHolder.getEntityName(),
inferredData.getPropertyName()
+ );
+
+ final XProperty property = inferredData.getProperty();
+ if ( property.isAnnotationPresent( Parent.class ) ) {
+ if ( propertyHolder.isComponent() ) {
+ propertyHolder.setParentProperty( property.getName() );
+ }
+ else {
+ throw new AnnotationException(
+ "@Parent cannot be applied outside an embeddable object: "
+ + BinderHelper.getPath( propertyHolder, inferredData )
+ );
+ }
+ return;
+ }
+
+ ColumnsBuilder columnsBuilder = new ColumnsBuilder(
+ propertyHolder, nullability, property, inferredData, entityBinder, mappings
+ ).extractMetadata();
+ Ejb3Column[] columns = columnsBuilder.getColumns();
+ Ejb3JoinColumn[] joinColumns = columnsBuilder.getJoinColumns();
+
+ final XClass returnedClass = inferredData.getClassOrElement();
+
+ //prepare PropertyBinder
+ PropertyBinder propertyBinder = new PropertyBinder();
+ propertyBinder.setName( inferredData.getPropertyName() );
+ propertyBinder.setReturnedClassName( inferredData.getTypeName() );
+ propertyBinder.setAccessType( inferredData.getDefaultAccess() );
+ propertyBinder.setHolder( propertyHolder );
+ propertyBinder.setProperty( property );
+ propertyBinder.setReturnedClass( inferredData.getPropertyClass() );
+ propertyBinder.setMappings( mappings );
+ if ( isIdentifierMapper ) {
+ propertyBinder.setInsertable( false );
+ propertyBinder.setUpdatable( false );
+ }
+ propertyBinder.setDeclaringClass( inferredData.getDeclaringClass() );
+ propertyBinder.setEntityBinder( entityBinder );
+ propertyBinder.setInheritanceStatePerClass( inheritanceStatePerClass );
+
+ boolean isId = !entityBinder.isIgnoreIdAnnotations() &&
+ ( property.isAnnotationPresent( Id.class )
+ || property.isAnnotationPresent( EmbeddedId.class ) );
+ propertyBinder.setId( isId );
+
+ if ( property.isAnnotationPresent( Version.class ) ) {
+ if ( isIdentifierMapper ) {
+ throw new AnnotationException(
+ "@IdClass class should not have @Version property"
+ );
+ }
+ if ( !( propertyHolder.getPersistentClass() instanceof RootClass ) ) {
+ throw new AnnotationException(
+ "Unable to define/override @Version on a subclass: "
+ + propertyHolder.getEntityName()
+ );
+ }
+ if ( !propertyHolder.isEntity() ) {
+ throw new AnnotationException(
+ "Unable to define @Version on an embedded class: "
+ + propertyHolder.getEntityName()
+ );
+ }
+ log.trace( "{} is a version property", inferredData.getPropertyName() );
+ RootClass rootClass = ( RootClass ) propertyHolder.getPersistentClass();
+ propertyBinder.setColumns( columns );
+ Property prop = propertyBinder.makePropertyValueAndBind();
+ propertyBinder.getSimpleValueBinder().setVersion( true );
+ rootClass.setVersion( prop );
+
+ //If version is on a mapped superclass, update the mapping
+ final org.hibernate.mapping.MappedSuperclass superclass =
BinderHelper.getMappedSuperclassOrNull(
+ inferredData.getDeclaringClass(),
+ inheritanceStatePerClass,
+ mappings
+ );
+ if ( superclass != null ) {
+ superclass.setDeclaredVersion( prop );
+ }
+ else {
+ //we know the property is on the actual entity
+ rootClass.setDeclaredVersion( prop );
+ }
+
+ SimpleValue simpleValue = ( SimpleValue ) prop.getValue();
+ simpleValue.setNullValue( "undefined" );
+ rootClass.setOptimisticLockMode( Versioning.OPTIMISTIC_LOCK_VERSION );
+ log.trace(
+ "Version name: {}, unsavedValue: {}", rootClass.getVersion().getName(),
+ ( ( SimpleValue ) rootClass.getVersion().getValue() ).getNullValue()
+ );
+ }
+ else {
+ final boolean forcePersist = property.isAnnotationPresent( MapsId.class )
+ || property.isAnnotationPresent( Id.class );
+ if ( property.isAnnotationPresent( ManyToOne.class ) ) {
+ ManyToOne ann = property.getAnnotation( ManyToOne.class );
+
+ //check validity
+ if ( property.isAnnotationPresent( Column.class )
+ || property.isAnnotationPresent( Columns.class ) ) {
+ throw new AnnotationException(
+ "@Column(s) not allowed on a @ManyToOne property: "
+ + BinderHelper.getPath( propertyHolder, inferredData )
+ );
+ }
+
+ Cascade hibernateCascade = property.getAnnotation( Cascade.class );
+ NotFound notFound = property.getAnnotation( NotFound.class );
+ boolean ignoreNotFound = notFound != null && notFound.action().equals(
NotFoundAction.IGNORE );
+ OnDelete onDeleteAnn = property.getAnnotation( OnDelete.class );
+ boolean onDeleteCascade = onDeleteAnn != null &&
OnDeleteAction.CASCADE.equals( onDeleteAnn.action() );
+ JoinTable assocTable = propertyHolder.getJoinTable( property );
+ if ( assocTable != null ) {
+ Join join = propertyHolder.addJoin( assocTable, false );
+ for ( Ejb3JoinColumn joinColumn : joinColumns ) {
+ joinColumn.setSecondaryTableName( join.getTable().getName() );
+ }
+ }
+ final boolean mandatory = !ann.optional() || forcePersist;
+ bindManyToOne(
+ getCascadeStrategy( ann.cascade(), hibernateCascade, false, forcePersist ),
+ joinColumns,
+ !mandatory,
+ ignoreNotFound, onDeleteCascade,
+ ToOneBinder.getTargetEntity( inferredData, mappings ),
+ propertyHolder,
+ inferredData, false, isIdentifierMapper,
+ inSecondPass, propertyBinder, mappings
+ );
+ }
+ else if ( property.isAnnotationPresent( OneToOne.class ) ) {
+ OneToOne ann = property.getAnnotation( OneToOne.class );
+
+ //check validity
+ if ( property.isAnnotationPresent( Column.class )
+ || property.isAnnotationPresent( Columns.class ) ) {
+ throw new AnnotationException(
+ "@Column(s) not allowed on a @OneToOne property: "
+ + BinderHelper.getPath( propertyHolder, inferredData )
+ );
+ }
+
+ //FIXME support a proper PKJCs
+ boolean trueOneToOne = property.isAnnotationPresent( PrimaryKeyJoinColumn.class )
+ || property.isAnnotationPresent( PrimaryKeyJoinColumns.class );
+ Cascade hibernateCascade = property.getAnnotation( Cascade.class );
+ NotFound notFound = property.getAnnotation( NotFound.class );
+ boolean ignoreNotFound = notFound != null && notFound.action().equals(
NotFoundAction.IGNORE );
+ OnDelete onDeleteAnn = property.getAnnotation( OnDelete.class );
+ boolean onDeleteCascade = onDeleteAnn != null &&
OnDeleteAction.CASCADE.equals( onDeleteAnn.action() );
+ JoinTable assocTable = propertyHolder.getJoinTable( property );
+ if ( assocTable != null ) {
+ Join join = propertyHolder.addJoin( assocTable, false );
+ for ( Ejb3JoinColumn joinColumn : joinColumns ) {
+ joinColumn.setSecondaryTableName( join.getTable().getName() );
+ }
+ }
+ //MapsId means the columns belong to the pk => not null
+ //@PKJC must be constrained
+ final boolean mandatory = !ann.optional() || forcePersist || trueOneToOne;
+ bindOneToOne(
+ getCascadeStrategy( ann.cascade(), hibernateCascade, ann.orphanRemoval(),
forcePersist ),
+ joinColumns,
+ !mandatory,
+ getFetchMode( ann.fetch() ),
+ ignoreNotFound, onDeleteCascade,
+ ToOneBinder.getTargetEntity( inferredData, mappings ),
+ propertyHolder,
+ inferredData,
+ ann.mappedBy(),
+ trueOneToOne,
+ isIdentifierMapper,
+ inSecondPass,
+ propertyBinder,
+ mappings
+ );
+ }
+ else if ( property.isAnnotationPresent( org.hibernate.annotations.Any.class ) ) {
+
+ //check validity
+ if ( property.isAnnotationPresent( Column.class )
+ || property.isAnnotationPresent( Columns.class ) ) {
+ throw new AnnotationException(
+ "@Column(s) not allowed on a @Any property: "
+ + BinderHelper.getPath( propertyHolder, inferredData )
+ );
+ }
+
+ Cascade hibernateCascade = property.getAnnotation( Cascade.class );
+ OnDelete onDeleteAnn = property.getAnnotation( OnDelete.class );
+ boolean onDeleteCascade = onDeleteAnn != null &&
OnDeleteAction.CASCADE.equals( onDeleteAnn.action() );
+ JoinTable assocTable = propertyHolder.getJoinTable( property );
+ if ( assocTable != null ) {
+ Join join = propertyHolder.addJoin( assocTable, false );
+ for ( Ejb3JoinColumn joinColumn : joinColumns ) {
+ joinColumn.setSecondaryTableName( join.getTable().getName() );
+ }
+ }
+ bindAny(
+ getCascadeStrategy( null, hibernateCascade, false, forcePersist ),
+ //@Any has not cascade attribute
+ joinColumns,
+ onDeleteCascade,
+ nullability,
+ propertyHolder,
+ inferredData,
+ entityBinder,
+ isIdentifierMapper,
+ mappings
+ );
+ }
+ else if ( property.isAnnotationPresent( OneToMany.class )
+ || property.isAnnotationPresent( ManyToMany.class )
+ || property.isAnnotationPresent( CollectionOfElements.class ) //legacy Hibernate
+ || property.isAnnotationPresent( ElementCollection.class )
+ || property.isAnnotationPresent( ManyToAny.class ) ) {
+ OneToMany oneToManyAnn = property.getAnnotation( OneToMany.class );
+ ManyToMany manyToManyAnn = property.getAnnotation( ManyToMany.class );
+ ElementCollection elementCollectionAnn = property.getAnnotation(
ElementCollection.class );
+ CollectionOfElements collectionOfElementsAnn = property.getAnnotation(
CollectionOfElements.class ); //legacy hibernate
+
+ final IndexColumn indexColumn;
+
+ if ( property.isAnnotationPresent( OrderColumn.class ) ) {
+ indexColumn = IndexColumn.buildColumnFromAnnotation(
+ property.getAnnotation( OrderColumn.class ),
+ propertyHolder,
+ inferredData,
+ entityBinder.getSecondaryTables(),
+ mappings
+ );
+ }
+ else {
+ //if @IndexColumn is not there, the generated IndexColumn is an implicit column and
not used.
+ //so we can leave the legacy processing as the default
+ indexColumn = IndexColumn.buildColumnFromAnnotation(
+ property.getAnnotation( org.hibernate.annotations.IndexColumn.class ),
+ propertyHolder,
+ inferredData,
+ mappings
+ );
+ }
+ CollectionBinder collectionBinder = CollectionBinder.getCollectionBinder(
+ propertyHolder.getEntityName(),
+ property,
+ !indexColumn.isImplicit(),
+ property.isAnnotationPresent( CollectionOfElements.class )
+ || property.isAnnotationPresent( org.hibernate.annotations.MapKey.class )
+ // || property.isAnnotationPresent( ManyToAny.class )
+ );
+ collectionBinder.setIndexColumn( indexColumn );
+ MapKey mapKeyAnn = property.getAnnotation( MapKey.class );
+ collectionBinder.setMapKey( mapKeyAnn );
+ collectionBinder.setPropertyName( inferredData.getPropertyName() );
+ BatchSize batchAnn = property.getAnnotation( BatchSize.class );
+ collectionBinder.setBatchSize( batchAnn );
+ javax.persistence.OrderBy ejb3OrderByAnn = property.getAnnotation(
javax.persistence.OrderBy.class );
+ OrderBy orderByAnn = property.getAnnotation( OrderBy.class );
+ collectionBinder.setEjb3OrderBy( ejb3OrderByAnn );
+ collectionBinder.setSqlOrderBy( orderByAnn );
+ Sort sortAnn = property.getAnnotation( Sort.class );
+ collectionBinder.setSort( sortAnn );
+ Cache cachAnn = property.getAnnotation( Cache.class );
+ collectionBinder.setCache( cachAnn );
+ collectionBinder.setPropertyHolder( propertyHolder );
+ Cascade hibernateCascade = property.getAnnotation( Cascade.class );
+ NotFound notFound = property.getAnnotation( NotFound.class );
+ boolean ignoreNotFound = notFound != null && notFound.action().equals(
NotFoundAction.IGNORE );
+ collectionBinder.setIgnoreNotFound( ignoreNotFound );
+ collectionBinder.setCollectionType( inferredData.getProperty().getElementClass() );
+ collectionBinder.setMappings( mappings );
+ collectionBinder.setAccessType( inferredData.getDefaultAccess() );
+
+ Ejb3Column[] elementColumns;
+ //do not use "element" if you are a JPA 2 @ElementCollection only for
legacy Hibernate mappings
+ boolean isJPA2ForValueMapping = property.isAnnotationPresent( ElementCollection.class
);
+ PropertyData virtualProperty = isJPA2ForValueMapping ? inferredData : new
WrappedInferredData(
+ inferredData, "element"
+ );
+ if ( property.isAnnotationPresent( Column.class ) || property.isAnnotationPresent(
+ Formula.class
+ ) ) {
+ Column ann = property.getAnnotation( Column.class );
+ Formula formulaAnn = property.getAnnotation( Formula.class );
+ elementColumns = Ejb3Column.buildColumnFromAnnotation(
+ new Column[] { ann },
+ formulaAnn,
+ nullability,
+ propertyHolder,
+ virtualProperty,
+ entityBinder.getSecondaryTables(),
+ mappings
+ );
+ }
+ else if ( property.isAnnotationPresent( Columns.class ) ) {
+ Columns anns = property.getAnnotation( Columns.class );
+ elementColumns = Ejb3Column.buildColumnFromAnnotation(
+ anns.columns(), null, nullability, propertyHolder, virtualProperty,
+ entityBinder.getSecondaryTables(), mappings
+ );
+ }
+ else {
+ elementColumns = Ejb3Column.buildColumnFromAnnotation(
+ null,
+ null,
+ nullability,
+ propertyHolder,
+ virtualProperty,
+ entityBinder.getSecondaryTables(),
+ mappings
+ );
+ }
+ {
+ Column[] keyColumns = null;
+ //JPA 2 has priority and has different default column values, differenciate legacy
from JPA 2
+ Boolean isJPA2 = null;
+ if ( property.isAnnotationPresent( MapKeyColumn.class ) ) {
+ isJPA2 = Boolean.TRUE;
+ keyColumns = new Column[] { new MapKeyColumnDelegator( property.getAnnotation(
MapKeyColumn.class ) ) };
+ }
+ else if ( property.isAnnotationPresent( org.hibernate.annotations.MapKey.class ) )
{
+ if ( isJPA2 == null ) {
+ isJPA2 = Boolean.FALSE;
+ }
+ keyColumns = property.getAnnotation( org.hibernate.annotations.MapKey.class
).columns();
+ }
+
+ //not explicitly legacy
+ if ( isJPA2 == null ) {
+ isJPA2 = Boolean.TRUE;
+ }
+
+ //nullify empty array
+ keyColumns = keyColumns != null && keyColumns.length > 0 ? keyColumns :
null;
+
+ //"mapkey" is the legacy column name of the key column pre JPA 2
+ PropertyData mapKeyVirtualProperty = new WrappedInferredData( inferredData,
"mapkey" );
+ Ejb3Column[] mapColumns = Ejb3Column.buildColumnFromAnnotation(
+ keyColumns,
+ null,
+ Nullability.FORCED_NOT_NULL,
+ propertyHolder,
+ isJPA2 ? inferredData : mapKeyVirtualProperty,
+ isJPA2 ? "_KEY" : null,
+ entityBinder.getSecondaryTables(),
+ mappings
+ );
+ collectionBinder.setMapKeyColumns( mapColumns );
+ }
+ {
+ JoinColumn[] joinKeyColumns = null;
+ //JPA 2 has priority and has different default column values, differenciate legacy
from JPA 2
+ Boolean isJPA2 = null;
+ if ( property.isAnnotationPresent( MapKeyJoinColumns.class ) ) {
+ isJPA2 = Boolean.TRUE;
+ final MapKeyJoinColumn[] mapKeyJoinColumns = property.getAnnotation(
MapKeyJoinColumns.class )
+ .value();
+ joinKeyColumns = new JoinColumn[mapKeyJoinColumns.length];
+ int index = 0;
+ for ( MapKeyJoinColumn joinColumn : mapKeyJoinColumns ) {
+ joinKeyColumns[index] = new MapKeyJoinColumnDelegator( joinColumn );
+ index++;
+ }
+ if ( joinKeyColumns != null ) {
+ throw new AnnotationException(
+ "@MapKeyJoinColumn and @MapKeyJoinColumns used on the same property:
"
+ + BinderHelper.getPath( propertyHolder, inferredData )
+ );
+ }
+ }
+ else if ( property.isAnnotationPresent( MapKeyJoinColumn.class ) ) {
+ isJPA2 = Boolean.TRUE;
+ joinKeyColumns = new JoinColumn[] {
+ new MapKeyJoinColumnDelegator(
+ property.getAnnotation(
+ MapKeyJoinColumn.class
+ )
+ )
+ };
+ }
+ else if ( property.isAnnotationPresent(
org.hibernate.annotations.MapKeyManyToMany.class ) ) {
+ if ( isJPA2 == null ) {
+ isJPA2 = Boolean.FALSE;
+ }
+ joinKeyColumns = property.getAnnotation(
org.hibernate.annotations.MapKeyManyToMany.class )
+ .joinColumns();
+ }
+
+ //not explicitly legacy
+ if ( isJPA2 == null ) {
+ isJPA2 = Boolean.TRUE;
+ }
+
+ PropertyData mapKeyVirtualProperty = new WrappedInferredData( inferredData,
"mapkey" );
+ Ejb3JoinColumn[] mapJoinColumns =
Ejb3JoinColumn.buildJoinColumnsWithDefaultColumnSuffix(
+ joinKeyColumns,
+ null,
+ entityBinder.getSecondaryTables(),
+ propertyHolder,
+ isJPA2 ? inferredData.getPropertyName() :
mapKeyVirtualProperty.getPropertyName(),
+ isJPA2 ? "_KEY" : null,
+ mappings
+ );
+ collectionBinder.setMapKeyManyToManyColumns( mapJoinColumns );
+ }
+
+ //potential element
+ collectionBinder.setEmbedded( property.isAnnotationPresent( Embedded.class ) );
+ collectionBinder.setElementColumns( elementColumns );
+ collectionBinder.setProperty( property );
+
+ //TODO enhance exception with @ManyToAny and @CollectionOfElements
+ if ( oneToManyAnn != null && manyToManyAnn != null ) {
+ throw new AnnotationException(
+ "@OneToMany and @ManyToMany on the same property is not allowed: "
+ + propertyHolder.getEntityName() + "." +
inferredData.getPropertyName()
+ );
+ }
+ String mappedBy = null;
+ if ( oneToManyAnn != null ) {
+ for ( Ejb3JoinColumn column : joinColumns ) {
+ if ( column.isSecondary() ) {
+ throw new NotYetImplementedException( "Collections having FK in secondary
table" );
+ }
+ }
+ collectionBinder.setFkJoinColumns( joinColumns );
+ mappedBy = oneToManyAnn.mappedBy();
+ collectionBinder.setTargetEntity(
+ mappings.getReflectionManager().toXClass( oneToManyAnn.targetEntity() )
+ );
+ collectionBinder.setCascadeStrategy(
+ getCascadeStrategy(
+ oneToManyAnn.cascade(), hibernateCascade, oneToManyAnn.orphanRemoval(), false
+ )
+ );
+ collectionBinder.setOneToMany( true );
+ }
+ else if ( elementCollectionAnn != null
+ || collectionOfElementsAnn != null //Hibernate legacy
+ ) {
+ for ( Ejb3JoinColumn column : joinColumns ) {
+ if ( column.isSecondary() ) {
+ throw new NotYetImplementedException( "Collections having FK in secondary
table" );
+ }
+ }
+ collectionBinder.setFkJoinColumns( joinColumns );
+ mappedBy = "";
+ final Class<?> targetElement = elementCollectionAnn != null ?
+ elementCollectionAnn.targetClass() :
+ collectionOfElementsAnn.targetElement();
+ collectionBinder.setTargetEntity(
+ mappings.getReflectionManager().toXClass( targetElement )
+ );
+ //collectionBinder.setCascadeStrategy( getCascadeStrategy(
embeddedCollectionAnn.cascade(), hibernateCascade ) );
+ collectionBinder.setOneToMany( true );
+ }
+ else if ( manyToManyAnn != null ) {
+ mappedBy = manyToManyAnn.mappedBy();
+ collectionBinder.setTargetEntity(
+ mappings.getReflectionManager().toXClass( manyToManyAnn.targetEntity() )
+ );
+ collectionBinder.setCascadeStrategy(
+ getCascadeStrategy(
+ manyToManyAnn.cascade(), hibernateCascade, false, false
+ )
+ );
+ collectionBinder.setOneToMany( false );
+ }
+ else if ( property.isAnnotationPresent( ManyToAny.class ) ) {
+ mappedBy = "";
+ collectionBinder.setTargetEntity(
+ mappings.getReflectionManager().toXClass( void.class )
+ );
+ collectionBinder.setCascadeStrategy( getCascadeStrategy( null, hibernateCascade,
false, false ) );
+ collectionBinder.setOneToMany( false );
+ }
+ collectionBinder.setMappedBy( mappedBy );
+
+ bindJoinedTableAssociation(
+ property, mappings, entityBinder, collectionBinder, propertyHolder, inferredData,
mappedBy
+ );
+
+ OnDelete onDeleteAnn = property.getAnnotation( OnDelete.class );
+ boolean onDeleteCascade = onDeleteAnn != null &&
OnDeleteAction.CASCADE.equals( onDeleteAnn.action() );
+ collectionBinder.setCascadeDeleteEnabled( onDeleteCascade );
+ if ( isIdentifierMapper ) {
+ collectionBinder.setInsertable( false );
+ collectionBinder.setUpdatable( false );
+ }
+ if ( property.isAnnotationPresent( CollectionId.class ) ) { //do not compute the
generators unless necessary
+ HashMap<String, IdGenerator> localGenerators = ( HashMap<String,
IdGenerator> ) classGenerators.clone();
+ localGenerators.putAll( buildLocalGenerators( property, mappings ) );
+ collectionBinder.setLocalGenerators( localGenerators );
+
+ }
+ collectionBinder.setInheritanceStatePerClass( inheritanceStatePerClass );
+ collectionBinder.setDeclaringClass( inferredData.getDeclaringClass() );
+ collectionBinder.bind();
+
+ }
+ //Either a regular property or a basic @Id or @EmbeddedId while not ignoring id
annotations
+ else if ( !isId || !entityBinder.isIgnoreIdAnnotations() ) {
+ //define whether the type is a component or not
+
+ boolean isComponent = false;
+
+ //Overrides from @MapsId if needed
+ boolean isOverridden = false;
+ if ( isId || propertyHolder.isOrWithinEmbeddedId() || propertyHolder.isInIdClass() )
{
+ //the associated entity could be using an @IdClass making the overridden property a
component
+ final PropertyData overridingProperty =
BinderHelper.getPropertyOverriddenByMapperOrMapsId(
+ isId, propertyHolder, property.getName(), mappings
+ );
+ if ( overridingProperty != null ) {
+ isOverridden = true;
+ final InheritanceState state = inheritanceStatePerClass.get(
overridingProperty.getClassOrElement() );
+ if ( state != null ) {
+ isComponent = isComponent || state.hasIdClassOrEmbeddedId();
+ }
+ //Get the new column
+ columns = columnsBuilder.overrideColumnFromMapperOrMapsIdProperty( isId );
+ }
+ }
+
+ isComponent = isComponent
+ || property.isAnnotationPresent( Embedded.class )
+ || property.isAnnotationPresent( EmbeddedId.class )
+ || returnedClass.isAnnotationPresent( Embeddable.class );
+
+
+ if ( isComponent ) {
+ String referencedEntityName = null;
+ if ( isOverridden ) {
+ final PropertyData mapsIdProperty =
BinderHelper.getPropertyOverriddenByMapperOrMapsId(
+ isId, propertyHolder, property.getName(), mappings
+ );
+ referencedEntityName = mapsIdProperty.getClassOrElementName();
+ }
+ AccessType propertyAccessor = entityBinder.getPropertyAccessor( property );
+ propertyBinder = bindComponent(
+ inferredData,
+ propertyHolder,
+ propertyAccessor,
+ entityBinder,
+ isIdentifierMapper,
+ mappings,
+ isComponentEmbedded,
+ isId,
+ inheritanceStatePerClass,
+ referencedEntityName,
+ isOverridden ? ( Ejb3JoinColumn[] ) columns : null
+ );
+ }
+ else {
+ //provide the basic property mapping
+ boolean optional = true;
+ boolean lazy = false;
+ if ( property.isAnnotationPresent( Basic.class ) ) {
+ Basic ann = property.getAnnotation( Basic.class );
+ optional = ann.optional();
+ lazy = ann.fetch() == FetchType.LAZY;
+ }
+ //implicit type will check basic types and Serializable classes
+ if ( isId || ( !optional && nullability != Nullability.FORCED_NULL ) ) {
+ //force columns to not null
+ for ( Ejb3Column col : columns ) {
+ col.forceNotNull();
+ }
+ }
+
+ propertyBinder.setLazy( lazy );
+ propertyBinder.setColumns( columns );
+ if ( isOverridden ) {
+ final PropertyData mapsIdProperty =
BinderHelper.getPropertyOverriddenByMapperOrMapsId(
+ isId, propertyHolder, property.getName(), mappings
+ );
+ propertyBinder.setReferencedEntityName( mapsIdProperty.getClassOrElementName() );
+ }
+
+ propertyBinder.makePropertyValueAndBind();
+
+ }
+ if ( isOverridden ) {
+ final PropertyData mapsIdProperty =
BinderHelper.getPropertyOverriddenByMapperOrMapsId(
+ isId, propertyHolder, property.getName(), mappings
+ );
+ Map<String, IdGenerator> localGenerators = ( HashMap<String,
IdGenerator> ) classGenerators.clone();
+ final IdGenerator foreignGenerator = new IdGenerator();
+ foreignGenerator.setIdentifierGeneratorStrategy( "assigned" );
+ foreignGenerator.setName( "Hibernate-local--foreign generator" );
+ foreignGenerator.setIdentifierGeneratorStrategy( "foreign" );
+ foreignGenerator.addParam( "property", mapsIdProperty.getPropertyName()
);
+ localGenerators.put( foreignGenerator.getName(), foreignGenerator );
+
+ BinderHelper.makeIdGenerator(
+ ( SimpleValue ) propertyBinder.getValue(),
+ foreignGenerator.getIdentifierGeneratorStrategy(),
+ foreignGenerator.getName(),
+ mappings,
+ localGenerators
+ );
+ }
+ if ( isId ) {
+ //components and regular basic types create SimpleValue objects
+ final SimpleValue value = ( SimpleValue ) propertyBinder.getValue();
+ if ( !isOverridden ) {
+ processId(
+ propertyHolder,
+ inferredData,
+ value,
+ classGenerators,
+ isIdentifierMapper,
+ mappings
+ );
+ }
+ }
+ }
+ }
+ //init index
+ //process indexes after everything: in second pass, many to one has to be done before
indexes
+ Index index = property.getAnnotation( Index.class );
+ if ( index != null ) {
+ if ( joinColumns != null ) {
+
+ for ( Ejb3Column column : joinColumns ) {
+ column.addIndex( index, inSecondPass );
+ }
+ }
+ else {
+ if ( columns != null ) {
+ for ( Ejb3Column column : columns ) {
+ column.addIndex( index, inSecondPass );
+ }
+ }
+ }
+ }
+
+ NaturalId naturalIdAnn = property.getAnnotation( NaturalId.class );
+ if ( naturalIdAnn != null ) {
+ if ( joinColumns != null ) {
+ for ( Ejb3Column column : joinColumns ) {
+ column.addUniqueKey( "_UniqueKey", inSecondPass );
+ }
+ }
+ else {
+ for ( Ejb3Column column : columns ) {
+ column.addUniqueKey( "_UniqueKey", inSecondPass );
+ }
+ }
+ }
+ }
+
+ private static void processId(
+ PropertyHolder propertyHolder,
+ PropertyData inferredData,
+ SimpleValue idValue,
+ HashMap<String, IdGenerator> classGenerators,
+ boolean isIdentifierMapper,
+ ExtendedMappings mappings) {
+ if ( isIdentifierMapper ) {
+ throw new AnnotationException(
+ "@IdClass class should not have @Id nor @EmbeddedId properties: "
+ + BinderHelper.getPath( propertyHolder, inferredData )
+ );
+ }
+ XClass returnedClass = inferredData.getClassOrElement();
+ XProperty property = inferredData.getProperty();
+ //clone classGenerator and override with local values
+ HashMap<String, IdGenerator> localGenerators = ( HashMap<String,
IdGenerator> ) classGenerators.clone();
+ localGenerators.putAll( buildLocalGenerators( property, mappings ) );
+
+ //manage composite related metadata
+ //guess if its a component and find id data access (property, field etc)
+ final boolean isComponent = returnedClass.isAnnotationPresent( Embeddable.class )
+ || property.isAnnotationPresent( EmbeddedId.class );
+
+ GeneratedValue generatedValue = property.getAnnotation( GeneratedValue.class );
+ String generatorType = generatedValue != null ?
+ generatorType( generatedValue.strategy(), mappings ) :
+ "assigned";
+ String generatorName = generatedValue != null ?
+ generatedValue.generator() :
+ BinderHelper.ANNOTATION_STRING_DEFAULT;
+ if ( isComponent ) {
+ generatorType = "assigned";
+ } //a component must not have any generator
+ BinderHelper.makeIdGenerator( idValue, generatorType, generatorName, mappings,
localGenerators );
+
+ log.trace(
+ "Bind {} on {}", ( isComponent ? "@EmbeddedId" : "@Id"
), inferredData.getPropertyName()
+ );
+ }
+
+ //TODO move that to collection binder?
+
+ private static void bindJoinedTableAssociation(
+ XProperty property, ExtendedMappings mappings, EntityBinder entityBinder,
+ CollectionBinder collectionBinder, PropertyHolder propertyHolder, PropertyData
inferredData,
+ String mappedBy
+ ) {
+ TableBinder associationTableBinder = new TableBinder();
+ JoinColumn[] annJoins;
+ JoinColumn[] annInverseJoins;
+ JoinTable assocTable = propertyHolder.getJoinTable( property );
+ CollectionTable collectionTable = property.getAnnotation( CollectionTable.class );
+
+ if ( assocTable != null || collectionTable != null ) {
+
+ final String catalog;
+ final String schema;
+ final String tableName;
+ final UniqueConstraint[] uniqueConstraints;
+ final JoinColumn[] joins;
+ final JoinColumn[] inverseJoins;
+
+ //JPA 2 has priority
+ if ( collectionTable != null ) {
+ catalog = collectionTable.catalog();
+ schema = collectionTable.schema();
+ tableName = collectionTable.name();
+ uniqueConstraints = collectionTable.uniqueConstraints();
+ joins = collectionTable.joinColumns();
+ inverseJoins = null;
+ }
+ else {
+ catalog = assocTable.catalog();
+ schema = assocTable.schema();
+ tableName = assocTable.name();
+ uniqueConstraints = assocTable.uniqueConstraints();
+ joins = assocTable.joinColumns();
+ inverseJoins = assocTable.inverseJoinColumns();
+ }
+
+ collectionBinder.setExplicitAssociationTable( true );
+
+ if ( !BinderHelper.isDefault( schema ) ) {
+ associationTableBinder.setSchema( schema );
+ }
+ if ( !BinderHelper.isDefault( catalog ) ) {
+ associationTableBinder.setCatalog( catalog );
+ }
+ if ( !BinderHelper.isDefault( tableName ) ) {
+ associationTableBinder.setName( tableName );
+ }
+ associationTableBinder.setUniqueConstraints( uniqueConstraints );
+
+ //set check constaint in the second pass
+ annJoins = joins.length == 0 ? null : joins;
+ annInverseJoins = inverseJoins == null || inverseJoins.length == 0 ? null :
inverseJoins;
+ }
+ else {
+ annJoins = null;
+ annInverseJoins = null;
+ }
+ Ejb3JoinColumn[] joinColumns = Ejb3JoinColumn.buildJoinTableJoinColumns(
+ annJoins, entityBinder.getSecondaryTables(), propertyHolder,
inferredData.getPropertyName(), mappedBy,
+ mappings
+ );
+ Ejb3JoinColumn[] inverseJoinColumns = Ejb3JoinColumn.buildJoinTableJoinColumns(
+ annInverseJoins, entityBinder.getSecondaryTables(), propertyHolder,
inferredData.getPropertyName(),
+ mappedBy, mappings
+ );
+ associationTableBinder.setMappings( mappings );
+ collectionBinder.setTableBinder( associationTableBinder );
+ collectionBinder.setJoinColumns( joinColumns );
+ collectionBinder.setInverseJoinColumns( inverseJoinColumns );
+ }
+
+ private static PropertyBinder bindComponent(
+ PropertyData inferredData,
+ PropertyHolder propertyHolder,
+ AccessType propertyAccessor,
+ EntityBinder entityBinder,
+ boolean isIdentifierMapper,
+ ExtendedMappings mappings,
+ boolean isComponentEmbedded,
+ boolean isId, //is a identifier
+ Map<XClass, InheritanceState> inheritanceStatePerClass,
+ String referencedEntityName, //is a component who is overridden by a @MapsId
+ Ejb3JoinColumn[] columns) {
+ Component comp;
+ if ( referencedEntityName != null ) {
+ comp = createComponent( propertyHolder, inferredData, isComponentEmbedded,
isIdentifierMapper, mappings );
+ SecondPass sp = new CopyIdentifierComponentSecondPass(
+ comp,
+ referencedEntityName,
+ columns,
+ mappings
+ );
+ mappings.addSecondPass( sp );
+ }
+ else {
+ comp = fillComponent(
+ propertyHolder, inferredData, propertyAccessor, !isId, entityBinder,
+ isComponentEmbedded, isIdentifierMapper,
+ false, mappings, inheritanceStatePerClass
+ );
+ }
+ if ( isId ) {
+ comp.setKey( true );
+ if ( propertyHolder.getPersistentClass().getIdentifier() != null ) {
+ throw new AnnotationException(
+ comp.getComponentClassName()
+ + " must not have @Id properties when used as an @EmbeddedId: "
+ + BinderHelper.getPath( propertyHolder, inferredData )
+ );
+ }
+ if ( referencedEntityName == null && comp.getPropertySpan() == 0 ) {
+ throw new AnnotationException(
+ comp.getComponentClassName()
+ + " has no persistent id property: "
+ + BinderHelper.getPath( propertyHolder, inferredData )
+ );
+ }
+ }
+ XProperty property = inferredData.getProperty();
+ setupComponentTuplizer( property, comp );
+ PropertyBinder binder = new PropertyBinder();
+ binder.setName( inferredData.getPropertyName() );
+ binder.setValue( comp );
+ binder.setProperty( inferredData.getProperty() );
+ binder.setAccessType( inferredData.getDefaultAccess() );
+ binder.setEmbedded( isComponentEmbedded );
+ binder.setHolder( propertyHolder );
+ binder.setId( isId );
+ binder.setEntityBinder( entityBinder );
+ binder.setInheritanceStatePerClass( inheritanceStatePerClass );
+ binder.setMappings( mappings );
+ binder.makePropertyAndBind();
+ return binder;
+ }
+
+ public static Component fillComponent(
+ PropertyHolder propertyHolder, PropertyData inferredData,
+ AccessType propertyAccessor, boolean isNullable,
+ EntityBinder entityBinder,
+ boolean isComponentEmbedded, boolean isIdentifierMapper, boolean inSecondPass,
+ ExtendedMappings mappings, Map<XClass, InheritanceState>
inheritanceStatePerClass
+ ) {
+
+ return fillComponent(
+ propertyHolder, inferredData, null, propertyAccessor,
+ isNullable, entityBinder, isComponentEmbedded, isIdentifierMapper, inSecondPass,
mappings,
+ inheritanceStatePerClass
+ );
+ }
+
+ public static Component fillComponent(
+ PropertyHolder propertyHolder, PropertyData inferredData,
+ PropertyData baseInferredData, //base inferred data correspond to the entity
reproducing inferredData's properties (ie IdClass)
+ AccessType propertyAccessor, boolean isNullable, EntityBinder entityBinder,
+ boolean isComponentEmbedded, boolean isIdentifierMapper, boolean inSecondPass,
ExtendedMappings mappings,
+ Map<XClass, InheritanceState> inheritanceStatePerClass
+ ) {
+
+ /**
+ * inSecondPass can only be used to apply right away the second pass of a
composite-element
+ * Because it's a value type, there is no bidirectional association, hence second
pass
+ * ordering does not matter
+ */
+ Component comp = createComponent( propertyHolder, inferredData, isComponentEmbedded,
isIdentifierMapper, mappings );
+ String subpath = BinderHelper.getPath( propertyHolder, inferredData );
+ log.trace( "Binding component with path: {}", subpath );
+ PropertyHolder subHolder = PropertyHolderBuilder.buildPropertyHolder(
+ comp, subpath,
+ inferredData, propertyHolder, mappings
+ );
+
+ final XClass xClassProcessed = inferredData.getPropertyClass();
+ List<PropertyData> classElements = new ArrayList<PropertyData>();
+ XClass returnedClassOrElement = inferredData.getClassOrElement();
+
+ List<PropertyData> baseClassElements = null;
+ Map<String, PropertyData> orderedBaseClassElements = new HashMap<String,
PropertyData>();
+ XClass baseReturnedClassOrElement;
+ if ( baseInferredData != null ) {
+ baseClassElements = new ArrayList<PropertyData>();
+ baseReturnedClassOrElement = baseInferredData.getClassOrElement();
+ bindTypeDefs( baseReturnedClassOrElement, mappings );
+ PropertyContainer propContainer = new PropertyContainer( baseReturnedClassOrElement,
xClassProcessed );
+ addElementsOfClass( baseClassElements, propertyAccessor, propContainer, mappings );
+ for ( PropertyData element : baseClassElements ) {
+ orderedBaseClassElements.put( element.getPropertyName(), element );
+ }
+ }
+
+ //embeddable elements can have type defs
+ bindTypeDefs( returnedClassOrElement, mappings );
+ PropertyContainer propContainer = new PropertyContainer( returnedClassOrElement,
xClassProcessed );
+ addElementsOfClass( classElements, propertyAccessor, propContainer, mappings );
+
+ //add elements of the embeddable superclass
+ XClass superClass = xClassProcessed.getSuperclass();
+ while ( superClass != null && superClass.isAnnotationPresent(
MappedSuperclass.class ) ) {
+ //FIXME: proper support of typevariables incl var resolved at upper levels
+ propContainer = new PropertyContainer( superClass, xClassProcessed );
+ addElementsOfClass( classElements, propertyAccessor, propContainer, mappings );
+ superClass = superClass.getSuperclass();
+ }
+ if ( baseClassElements != null ) {
+ //useful to avoid breaking pre JPA 2 mappings
+ if ( !hasAnnotationsOnIdClass( xClassProcessed ) ) {
+ for ( int i = 0; i < classElements.size(); i++ ) {
+ final PropertyData idClassPropertyData = classElements.get( i );
+ final PropertyData entityPropertyData = orderedBaseClassElements.get(
idClassPropertyData.getPropertyName() );
+ if ( propertyHolder.isInIdClass() ) {
+ if ( entityPropertyData == null ) {
+ throw new AnnotationException(
+ "Property of @IdClass not found in entity "
+ + baseInferredData.getPropertyClass().getName() + ": "
+ + idClassPropertyData.getPropertyName()
+ );
+ }
+ final boolean hasXToOneAnnotation = entityPropertyData.getProperty()
+ .isAnnotationPresent( ManyToOne.class )
+ || entityPropertyData.getProperty().isAnnotationPresent( OneToOne.class );
+ final boolean isOfDifferentType = !entityPropertyData.getClassOrElement()
+ .equals( idClassPropertyData.getClassOrElement() );
+ if ( hasXToOneAnnotation && isOfDifferentType ) {
+ //don't replace here as we need to use the actual original return type
+ //the annotation overriding will be dealt with by a mechanism similar to @MapsId
+ }
+ else {
+ classElements.set( i, entityPropertyData ); //this works since they are in the
same order
+ }
+ }
+ else {
+ classElements.set( i, entityPropertyData ); //this works since they are in the
same order
+ }
+ }
+ }
+ }
+ for ( PropertyData propertyAnnotatedElement : classElements ) {
+ processElementAnnotations(
+ subHolder, isNullable ?
+ Nullability.NO_CONSTRAINT :
+ Nullability.FORCED_NOT_NULL,
+ propertyAnnotatedElement,
+ new HashMap<String, IdGenerator>(), entityBinder, isIdentifierMapper,
isComponentEmbedded,
+ inSecondPass, mappings, inheritanceStatePerClass
+ );
+
+ XProperty property = propertyAnnotatedElement.getProperty();
+ if ( property.isAnnotationPresent( GeneratedValue.class ) &&
+ property.isAnnotationPresent( Id.class ) ) {
+ //clone classGenerator and override with local values
+ Map<String, IdGenerator> localGenerators = new HashMap<String,
IdGenerator>();
+ localGenerators.putAll( buildLocalGenerators( property, mappings ) );
+
+ GeneratedValue generatedValue = property.getAnnotation( GeneratedValue.class );
+ String generatorType = generatedValue != null ? generatorType(
+ generatedValue.strategy(), mappings
+ ) : "assigned";
+ String generator = generatedValue != null ? generatedValue.generator() :
BinderHelper.ANNOTATION_STRING_DEFAULT;
+
+ BinderHelper.makeIdGenerator(
+ ( SimpleValue ) comp.getProperty( property.getName() ).getValue(),
+ generatorType,
+ generator,
+ mappings,
+ localGenerators
+ );
+ }
+
+ }
+ return comp;
+ }
+
+ public static Component createComponent(
+ PropertyHolder propertyHolder,
+ PropertyData inferredData,
+ boolean isComponentEmbedded,
+ boolean isIdentifierMapper,
+ ExtendedMappings mappings) {
+ Component comp = new Component( mappings, propertyHolder.getPersistentClass() );
+ comp.setEmbedded( isComponentEmbedded );
+ //yuk
+ comp.setTable( propertyHolder.getTable() );
+ //FIXME shouldn't identifier mapper use getClassOrElementName? Need to be checked.
+ if ( isIdentifierMapper || ( isComponentEmbedded &&
inferredData.getPropertyName() == null ) ) {
+ comp.setComponentClassName( comp.getOwner().getClassName() );
+ }
+ else {
+ comp.setComponentClassName( inferredData.getClassOrElementName() );
+ }
+ comp.setNodeName( inferredData.getPropertyName() );
+ return comp;
+ }
+
+ private static void bindIdClass(
+ String generatorType, String generatorName, PropertyData inferredData,
+ PropertyData baseInferredData, Ejb3Column[] columns, PropertyHolder propertyHolder,
+ boolean isComposite,
+ AccessType propertyAccessor, EntityBinder entityBinder, boolean isEmbedded,
+ boolean isIdentifierMapper, ExtendedMappings mappings,
+ Map<XClass, InheritanceState> inheritanceStatePerClass
+ ) {
+
+ /*
+ * Fill simple value and property since and Id is a property
+ */
+ PersistentClass persistentClass = propertyHolder.getPersistentClass();
+ if ( !( persistentClass instanceof RootClass ) ) {
+ throw new AnnotationException(
+ "Unable to define/override @Id(s) on a subclass: "
+ + propertyHolder.getEntityName()
+ );
+ }
+ RootClass rootClass = ( RootClass ) persistentClass;
+ String persistentClassName = rootClass.getClassName();
+ SimpleValue id;
+ final String propertyName = inferredData.getPropertyName();
+ HashMap<String, IdGenerator> localGenerators = new HashMap<String,
IdGenerator>();
+ if ( isComposite ) {
+ id = fillComponent(
+ propertyHolder, inferredData, baseInferredData, propertyAccessor,
+ false, entityBinder, isEmbedded, isIdentifierMapper, false, mappings,
inheritanceStatePerClass
+ );
+ Component componentId = ( Component ) id;
+ componentId.setKey( true );
+ if ( rootClass.getIdentifier() != null ) {
+ throw new AnnotationException( componentId.getComponentClassName() + " must not
have @Id properties when used as an @EmbeddedId" );
+ }
+ if ( componentId.getPropertySpan() == 0 ) {
+ throw new AnnotationException( componentId.getComponentClassName() + " has no
persistent id property" );
+ }
+ //tuplizers
+ XProperty property = inferredData.getProperty();
+ setupComponentTuplizer( property, componentId );
+ }
+ else {
+ //TODO I think this branch is never used. Remove.
+
+ for ( Ejb3Column column : columns ) {
+ column.forceNotNull(); //this is an id
+ }
+ SimpleValueBinder value = new SimpleValueBinder();
+ value.setPropertyName( propertyName );
+ value.setReturnedClassName( inferredData.getTypeName() );
+ value.setColumns( columns );
+ value.setPersistentClassName( persistentClassName );
+ value.setMappings( mappings );
+ value.setType( inferredData.getProperty(), inferredData.getClassOrElement() );
+ id = value.make();
+ }
+ rootClass.setIdentifier( id );
+ BinderHelper.makeIdGenerator( id, generatorType, generatorName, mappings,
localGenerators );
+ if ( isEmbedded ) {
+ rootClass.setEmbeddedIdentifier( inferredData.getPropertyClass() == null );
+ }
+ else {
+ PropertyBinder binder = new PropertyBinder();
+ binder.setName( propertyName );
+ binder.setValue( id );
+ binder.setAccessType( inferredData.getDefaultAccess() );
+ binder.setProperty( inferredData.getProperty() );
+ Property prop = binder.makeProperty();
+ rootClass.setIdentifierProperty( prop );
+ //if the id property is on a superclass, update the metamodel
+ final org.hibernate.mapping.MappedSuperclass superclass =
BinderHelper.getMappedSuperclassOrNull(
+ inferredData.getDeclaringClass(),
+ inheritanceStatePerClass,
+ mappings
+ );
+ if ( superclass != null ) {
+ superclass.setDeclaredIdentifierProperty( prop );
+ }
+ else {
+ //we know the property is on the actual entity
+ rootClass.setDeclaredIdentifierProperty( prop );
+ }
+ }
+ }
+
+ private static PropertyData getUniqueIdPropertyFromBaseClass(
+ PropertyData inferredData,
+ PropertyData baseInferredData,
+ AccessType propertyAccessor,
+ ExtendedMappings mappings) {
+ List<PropertyData> baseClassElements = new ArrayList<PropertyData>();
+ XClass baseReturnedClassOrElement = baseInferredData.getClassOrElement();
+ PropertyContainer propContainer = new PropertyContainer(
+ baseReturnedClassOrElement, inferredData.getPropertyClass()
+ );
+ addElementsOfClass( baseClassElements, propertyAccessor, propContainer, mappings );
+ //Id properties are on top and there is only one
+ return baseClassElements.get( 0 );
+ }
+
+ private static void setupComponentTuplizer(XProperty property, Component component) {
+ if ( property == null ) {
+ return;
+ }
+ if ( property.isAnnotationPresent( Tuplizers.class ) ) {
+ for ( Tuplizer tuplizer : property.getAnnotation( Tuplizers.class ).value() ) {
+ EntityMode mode = EntityMode.parse( tuplizer.entityMode() );
+ component.addTuplizer( mode, tuplizer.impl().getName() );
+ }
+ }
+ if ( property.isAnnotationPresent( Tuplizer.class ) ) {
+ Tuplizer tuplizer = property.getAnnotation( Tuplizer.class );
+ EntityMode mode = EntityMode.parse( tuplizer.entityMode() );
+ component.addTuplizer( mode, tuplizer.impl().getName() );
+ }
+ }
+
+ private static void bindManyToOne(
+ String cascadeStrategy, Ejb3JoinColumn[] columns, boolean optional,
+ boolean ignoreNotFound, boolean cascadeOnDelete,
+ XClass targetEntity, PropertyHolder propertyHolder,
+ PropertyData inferredData, boolean unique,
+ boolean isIdentifierMapper, boolean inSecondPass,
+ PropertyBinder propertyBinder,
+ ExtendedMappings mappings
+ ) {
+ //All FK columns should be in the same table
+ org.hibernate.mapping.ManyToOne value = new org.hibernate.mapping.ManyToOne( mappings,
columns[0].getTable() );
+ // This is a @OneToOne mapped to a physical o.h.mapping.ManyToOne
+ if ( unique ) {
+ value.markAsLogicalOneToOne();
+ }
+ value.setReferencedEntityName( ToOneBinder.getReferenceEntityName( inferredData,
targetEntity, mappings ) );
+ final XProperty property = inferredData.getProperty();
+ defineFetchingStrategy( value, property );
+ //value.setFetchMode( fetchMode );
+ value.setIgnoreNotFound( ignoreNotFound );
+ value.setCascadeDeleteEnabled( cascadeOnDelete );
+ //value.setLazy( fetchMode != FetchMode.JOIN );
+ if ( !optional ) {
+ for ( Ejb3JoinColumn column : columns ) {
+ column.setNullable( false );
+ }
+ }
+ if ( property.isAnnotationPresent( MapsId.class ) ) {
+ //read only
+ for ( Ejb3JoinColumn column : columns ) {
+ column.setInsertable( false );
+ column.setUpdatable( false );
+ }
+ }
+ value.setTypeName( inferredData.getClassOrElementName() );
+ final String propertyName = inferredData.getPropertyName();
+ value.setTypeUsingReflection( propertyHolder.getClassName(), propertyName );
+
+ ForeignKey fk = property.getAnnotation( ForeignKey.class );
+ String fkName = fk != null ?
+ fk.name() :
+ "";
+ if ( !BinderHelper.isDefault( fkName ) ) {
+ value.setForeignKeyName( fkName );
+ }
+
+ String path = propertyHolder.getPath() + "." + propertyName;
+ FkSecondPass secondPass = new ToOneFkSecondPass(
+ value, columns,
+ !optional && unique, //cannot have nullable and unique on certain DBs like
Derby
+ propertyHolder.getEntityOwnerClassName(),
+ path, mappings
+ );
+ if ( inSecondPass ) {
+ secondPass.doSecondPass( mappings.getClasses() );
+ }
+ else {
+ mappings.addSecondPass(
+ secondPass
+ );
+ }
+ Ejb3Column.checkPropertyConsistency( columns, propertyHolder.getEntityName() +
propertyName );
+ //PropertyBinder binder = new PropertyBinder();
+ propertyBinder.setName( propertyName );
+ propertyBinder.setValue( value );
+ //binder.setCascade(cascadeStrategy);
+ if ( isIdentifierMapper ) {
+ propertyBinder.setInsertable( false );
+ propertyBinder.setUpdatable( false );
+ }
+ else {
+ propertyBinder.setInsertable( columns[0].isInsertable() );
+ propertyBinder.setUpdatable( columns[0].isUpdatable() );
+ }
+ propertyBinder.setColumns( columns );
+ propertyBinder.setAccessType( inferredData.getDefaultAccess() );
+ propertyBinder.setCascade( cascadeStrategy );
+ propertyBinder.setProperty( property );
+ propertyBinder.setXToMany( true );
+ propertyBinder.makePropertyAndBind();
+ }
+
+ protected static void defineFetchingStrategy(ToOne toOne, XProperty property) {
+ LazyToOne lazy = property.getAnnotation( LazyToOne.class );
+ Fetch fetch = property.getAnnotation( Fetch.class );
+ ManyToOne manyToOne = property.getAnnotation( ManyToOne.class );
+ OneToOne oneToOne = property.getAnnotation( OneToOne.class );
+ FetchType fetchType;
+ if ( manyToOne != null ) {
+ fetchType = manyToOne.fetch();
+ }
+ else if ( oneToOne != null ) {
+ fetchType = oneToOne.fetch();
+ }
+ else {
+ throw new AssertionFailure(
+ "Define fetch strategy on a property not annotated with @OneToMany nor
@OneToOne"
+ );
+ }
+ if ( lazy != null ) {
+ toOne.setLazy( !( lazy.value() == LazyToOneOption.FALSE ) );
+ toOne.setUnwrapProxy( ( lazy.value() == LazyToOneOption.NO_PROXY ) );
+ }
+ else {
+ toOne.setLazy( fetchType == FetchType.LAZY );
+ toOne.setUnwrapProxy( false );
+ }
+ if ( fetch != null ) {
+ if ( fetch.value() == org.hibernate.annotations.FetchMode.JOIN ) {
+ toOne.setFetchMode( FetchMode.JOIN );
+ toOne.setLazy( false );
+ toOne.setUnwrapProxy( false );
+ }
+ else if ( fetch.value() == org.hibernate.annotations.FetchMode.SELECT ) {
+ toOne.setFetchMode( FetchMode.SELECT );
+ }
+ else if ( fetch.value() == org.hibernate.annotations.FetchMode.SUBSELECT ) {
+ throw new AnnotationException( "Use of FetchMode.SUBSELECT not allowed on ToOne
associations" );
+ }
+ else {
+ throw new AssertionFailure( "Unknown FetchMode: " + fetch.value() );
+ }
+ }
+ else {
+ toOne.setFetchMode( getFetchMode( fetchType ) );
+ }
+ }
+
+ private static void bindOneToOne(
+ String cascadeStrategy,
+ Ejb3JoinColumn[] joinColumns,
+ boolean optional,
+ FetchMode fetchMode,
+ boolean ignoreNotFound,
+ boolean cascadeOnDelete,
+ XClass targetEntity,
+ PropertyHolder propertyHolder,
+ PropertyData inferredData, String mappedBy,
+ boolean trueOneToOne,
+ boolean isIdentifierMapper,
+ boolean inSecondPass,
+ PropertyBinder propertyBinder,
+ ExtendedMappings mappings
+ ) {
+ //column.getTable() => persistentClass.getTable()
+ final String propertyName = inferredData.getPropertyName();
+ log.trace( "Fetching {} with {}", propertyName, fetchMode );
+ boolean mapToPK = true;
+ if ( !trueOneToOne ) {
+ //try to find a hidden true one to one (FK == PK columns)
+ KeyValue identifier = propertyHolder.getIdentifier();
+ if ( identifier == null ) {
+ //this is a @OneToOne in a @EmbeddedId (the persistentClass.identifier is not set
yet, it's being built)
+ //by definition the PK cannot refers to itself so it cannot map to itself
+ mapToPK = false;
+ }
+ else {
+ Iterator idColumns = identifier.getColumnIterator();
+ List<String> idColumnNames = new ArrayList<String>();
+ org.hibernate.mapping.Column currentColumn;
+ if ( identifier.getColumnSpan() != joinColumns.length ) {
+ mapToPK = false;
+ }
+ else {
+ while ( idColumns.hasNext() ) {
+ currentColumn = ( org.hibernate.mapping.Column ) idColumns.next();
+ idColumnNames.add( currentColumn.getName() );
+ }
+ for ( Ejb3JoinColumn col : joinColumns ) {
+ if ( !idColumnNames.contains( col.getMappingColumn().getName() ) ) {
+ mapToPK = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if ( trueOneToOne || mapToPK || !BinderHelper.isDefault( mappedBy ) ) {
+ //is a true one-to-one
+ //FIXME referencedColumnName ignored => ordering may fail.
+ OneToOneSecondPass secondPass = new OneToOneSecondPass(
+ mappedBy,
+ propertyHolder.getEntityName(),
+ propertyName,
+ propertyHolder, inferredData, targetEntity, ignoreNotFound, cascadeOnDelete,
+ optional, cascadeStrategy, joinColumns, mappings
+ );
+ if ( inSecondPass ) {
+ secondPass.doSecondPass( mappings.getClasses() );
+ }
+ else {
+ mappings.addSecondPass(
+ secondPass, BinderHelper.isDefault( mappedBy )
+ );
+ }
+ }
+ else {
+ //has a FK on the table
+ bindManyToOne(
+ cascadeStrategy, joinColumns, optional, ignoreNotFound, cascadeOnDelete,
+ targetEntity,
+ propertyHolder, inferredData, true, isIdentifierMapper, inSecondPass,
+ propertyBinder, mappings
+ );
+ }
+ }
+
+ private static void bindAny(
+ String cascadeStrategy, Ejb3JoinColumn[] columns, boolean cascadeOnDelete, Nullability
nullability,
+ PropertyHolder propertyHolder, PropertyData inferredData, EntityBinder entityBinder,
+ boolean isIdentifierMapper, ExtendedMappings mappings
+ ) {
+ org.hibernate.annotations.Any anyAnn = inferredData.getProperty()
+ .getAnnotation( org.hibernate.annotations.Any.class );
+ if ( anyAnn == null ) {
+ throw new AssertionFailure(
+ "Missing @Any annotation: "
+ + BinderHelper.getPath( propertyHolder, inferredData )
+ );
+ }
+ Any value = BinderHelper.buildAnyValue(
+ anyAnn.metaDef(), columns, anyAnn.metaColumn(), inferredData,
+ cascadeOnDelete, nullability, propertyHolder, entityBinder, anyAnn.optional(),
mappings
+ );
+
+ PropertyBinder binder = new PropertyBinder();
+ binder.setName( inferredData.getPropertyName() );
+ binder.setValue( value );
+
+ binder.setLazy( anyAnn.fetch() == FetchType.LAZY );
+ //binder.setCascade(cascadeStrategy);
+ if ( isIdentifierMapper ) {
+ binder.setInsertable( false );
+ binder.setUpdatable( false );
+ }
+ else {
+ binder.setInsertable( columns[0].isInsertable() );
+ binder.setUpdatable( columns[0].isUpdatable() );
+ }
+ binder.setAccessType( inferredData.getDefaultAccess() );
+ binder.setCascade( cascadeStrategy );
+ Property prop = binder.makeProperty();
+ //composite FK columns are in the same table so its OK
+ propertyHolder.addProperty( prop, columns, inferredData.getDeclaringClass() );
+ }
+
+ private static String generatorType(GenerationType generatorEnum, ExtendedMappings
mappings) {
+ boolean useNewGeneratorMappings = mappings.useNewGeneratorMappings();
+ switch ( generatorEnum ) {
+ case IDENTITY:
+ return "identity";
+ case AUTO:
+ return useNewGeneratorMappings
+ ? org.hibernate.id.enhanced.SequenceStyleGenerator.class.getName()
+ : "native";
+ case TABLE:
+ return useNewGeneratorMappings
+ ? org.hibernate.id.enhanced.TableGenerator.class.getName()
+ : MultipleHiLoPerTableGenerator.class.getName();
+ case SEQUENCE:
+ return useNewGeneratorMappings
+ ? org.hibernate.id.enhanced.SequenceStyleGenerator.class.getName()
+ : "seqhilo";
+ }
+ throw new AssertionFailure( "Unknown GeneratorType: " + generatorEnum );
+ }
+
+ private static EnumSet<CascadeType>
convertToHibernateCascadeType(javax.persistence.CascadeType[] ejbCascades) {
+ EnumSet<CascadeType> hibernateCascadeSet = EnumSet.noneOf( CascadeType.class );
+ if ( ejbCascades != null && ejbCascades.length > 0 ) {
+ for ( javax.persistence.CascadeType cascade : ejbCascades ) {
+ switch ( cascade ) {
+ case ALL:
+ hibernateCascadeSet.add( CascadeType.ALL );
+ break;
+ case PERSIST:
+ hibernateCascadeSet.add( CascadeType.PERSIST );
+ break;
+ case MERGE:
+ hibernateCascadeSet.add( CascadeType.MERGE );
+ break;
+ case REMOVE:
+ hibernateCascadeSet.add( CascadeType.REMOVE );
+ break;
+ case REFRESH:
+ hibernateCascadeSet.add( CascadeType.REFRESH );
+ break;
+ case DETACH:
+ hibernateCascadeSet.add( CascadeType.DETACH );
+ break;
+ }
+ }
+ }
+
+ return hibernateCascadeSet;
+ }
+
+ private static String getCascadeStrategy(
+ javax.persistence.CascadeType[] ejbCascades, Cascade hibernateCascadeAnnotation,
+ boolean orphanRemoval, boolean forcePersist) {
+ EnumSet<CascadeType> hibernateCascadeSet = convertToHibernateCascadeType(
ejbCascades );
+ CascadeType[] hibernateCascades = hibernateCascadeAnnotation == null ?
+ null :
+ hibernateCascadeAnnotation.value();
+
+ if ( hibernateCascades != null && hibernateCascades.length > 0 ) {
+ hibernateCascadeSet.addAll( Arrays.asList( hibernateCascades ) );
+ }
+
+ if ( orphanRemoval ) {
+ hibernateCascadeSet.add( CascadeType.DELETE_ORPHAN );
+ hibernateCascadeSet.add( CascadeType.REMOVE );
+ }
+ if ( forcePersist ) {
+ hibernateCascadeSet.add( CascadeType.PERSIST );
+ }
+
+ StringBuilder cascade = new StringBuilder();
+ for ( CascadeType aHibernateCascadeSet : hibernateCascadeSet ) {
+ switch ( aHibernateCascadeSet ) {
+ case ALL:
+ cascade.append( "," ).append( "all" );
+ break;
+ case SAVE_UPDATE:
+ cascade.append( "," ).append( "save-update" );
+ break;
+ case PERSIST:
+ cascade.append( "," ).append( "persist" );
+ break;
+ case MERGE:
+ cascade.append( "," ).append( "merge" );
+ break;
+ case LOCK:
+ cascade.append( "," ).append( "lock" );
+ break;
+ case REFRESH:
+ cascade.append( "," ).append( "refresh" );
+ break;
+ case REPLICATE:
+ cascade.append( "," ).append( "replicate" );
+ break;
+ case EVICT:
+ case DETACH:
+ cascade.append( "," ).append( "evict" );
+ break;
+ case DELETE:
+ cascade.append( "," ).append( "delete" );
+ break;
+ case DELETE_ORPHAN:
+ cascade.append( "," ).append( "delete-orphan" );
+ break;
+ case REMOVE:
+ cascade.append( "," ).append( "delete" );
+ break;
+ }
+ }
+ return cascade.length() > 0 ?
+ cascade.substring( 1 ) :
+ "none";
+ }
+
+ public static FetchMode getFetchMode(FetchType fetch) {
+ if ( fetch == FetchType.EAGER ) {
+ return FetchMode.JOIN;
+ }
+ else {
+ return FetchMode.SELECT;
+ }
+ }
+
+ private static HashMap<String, IdGenerator> buildLocalGenerators(XAnnotatedElement
annElt, ExtendedMappings mappings) {
+ HashMap<String, IdGenerator> generators = new HashMap<String,
IdGenerator>();
+ TableGenerator tabGen = annElt.getAnnotation( TableGenerator.class );
+ SequenceGenerator seqGen = annElt.getAnnotation( SequenceGenerator.class );
+ GenericGenerator genGen = annElt.getAnnotation( GenericGenerator.class );
+ if ( tabGen != null ) {
+ IdGenerator idGen = buildIdGenerator( tabGen, mappings );
+ generators.put( idGen.getName(), idGen );
+ }
+ if ( seqGen != null ) {
+ IdGenerator idGen = buildIdGenerator( seqGen, mappings );
+ generators.put( idGen.getName(), idGen );
+ }
+ if ( genGen != null ) {
+ IdGenerator idGen = buildIdGenerator( genGen, mappings );
+ generators.put( idGen.getName(), idGen );
+ }
+ return generators;
+ }
+
+ public static boolean isDefault(XClass clazz, ExtendedMappings mappings) {
+ return mappings.getReflectionManager().equals( clazz, void.class );
+ }
+
+ /**
+ * For the mapped entities build some temporary data-structure containing information
about the
+ * inheritance status of a class.
+ *
+ * @param orderedClasses Order list of all annotated entities and their mapped
superclasses
+ *
+ * @return A map of {@code InheritanceState}s keyed against their {@code XClass}.
+ */
+ public static Map<XClass, InheritanceState> buildInheritanceStates(
+ List<XClass> orderedClasses,
+ ExtendedMappings mappings) {
+ ReflectionManager reflectionManager = mappings.getReflectionManager();
+ Map<XClass, InheritanceState> inheritanceStatePerClass = new HashMap<XClass,
InheritanceState>(
+ orderedClasses.size()
+ );
+ for ( XClass clazz : orderedClasses ) {
+ InheritanceState superclassState = InheritanceState.getSuperclassInheritanceState(
+ clazz, inheritanceStatePerClass
+ );
+ InheritanceState state = new InheritanceState( clazz, inheritanceStatePerClass,
mappings );
+ if ( superclassState != null ) {
+ //the classes are ordered thus preventing an NPE
+ //FIXME if an entity has subclasses annotated @MappedSperclass wo sub @Entity this is
wrong
+ superclassState.setHasSiblings( true );
+ InheritanceState superEntityState =
InheritanceState.getInheritanceStateOfSuperEntity(
+ clazz, inheritanceStatePerClass
+ );
+ state.setHasParents( superEntityState != null );
+ final boolean nonDefault = state.getType() != null &&
!InheritanceType.SINGLE_TABLE
+ .equals( state.getType() );
+ if ( superclassState.getType() != null ) {
+ final boolean mixingStrategy = state.getType() != null && !state.getType()
+ .equals( superclassState.getType() );
+ if ( nonDefault && mixingStrategy ) {
+ log.warn(
+ "Mixing inheritance strategy in a entity hierarchy is not allowed, ignoring
sub strategy in: {}",
+ clazz.getName()
+ );
+ }
+ state.setType( superclassState.getType() );
+ }
+ }
+ inheritanceStatePerClass.put( clazz, state );
+ }
+ return inheritanceStatePerClass;
+ }
+
+ private static boolean hasAnnotationsOnIdClass(XClass idClass) {
+// if(idClass.getAnnotation(Embeddable.class) != null)
+// return true;
+
+ List<XProperty> properties = idClass.getDeclaredProperties( XClass.ACCESS_FIELD
);
+ for ( XProperty property : properties ) {
+ if ( property.isAnnotationPresent( Column.class ) || property.isAnnotationPresent(
OneToMany.class ) ||
+ property.isAnnotationPresent( ManyToOne.class ) || property.isAnnotationPresent(
Id.class ) ||
+ property.isAnnotationPresent( GeneratedValue.class ) ||
property.isAnnotationPresent( OneToOne.class ) ||
+ property.isAnnotationPresent( ManyToMany.class )
+ ) {
+ return true;
+ }
+ }
+ List<XMethod> methods = idClass.getDeclaredMethods();
+ for ( XMethod method : methods ) {
+ if ( method.isAnnotationPresent( Column.class ) || method.isAnnotationPresent(
OneToMany.class ) ||
+ method.isAnnotationPresent( ManyToOne.class ) || method.isAnnotationPresent(
Id.class ) ||
+ method.isAnnotationPresent( GeneratedValue.class ) || method.isAnnotationPresent(
OneToOne.class ) ||
+ method.isAnnotationPresent( ManyToMany.class )
+ ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/AnnotationBinder.java
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,1586 @@
+// $Id$
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.ResourceBundle;
+import java.util.Set;
+import java.util.StringTokenizer;
+import javax.persistence.Embeddable;
+import javax.persistence.Entity;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.MapsId;
+
+import org.dom4j.Attribute;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.DuplicateMappingException;
+import org.hibernate.HibernateException;
+import org.hibernate.Interceptor;
+import org.hibernate.MappingException;
+import org.hibernate.SessionFactory;
+import org.hibernate.annotations.AnyMetaDef;
+import org.hibernate.annotations.Cache;
+import org.hibernate.annotations.common.AssertionFailure;
+import org.hibernate.annotations.common.reflection.MetadataProvider;
+import org.hibernate.annotations.common.reflection.MetadataProviderInjector;
+import org.hibernate.annotations.common.reflection.ReflectionManager;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.java.JavaReflectionManager;
+import org.hibernate.cfg.annotations.reflection.JPAMetadataProvider;
+import org.hibernate.cfg.beanvalidation.BeanValidationActivator;
+import org.hibernate.engine.NamedQueryDefinition;
+import org.hibernate.engine.NamedSQLQueryDefinition;
+import org.hibernate.engine.ResultSetMappingDefinition;
+import org.hibernate.event.EventListeners;
+import org.hibernate.event.PreInsertEventListener;
+import org.hibernate.event.PreUpdateEventListener;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.FetchProfile;
+import org.hibernate.mapping.IdGenerator;
+import org.hibernate.mapping.Join;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Table;
+import org.hibernate.mapping.UniqueKey;
+import org.hibernate.util.CollectionHelper;
+import org.hibernate.util.JoinedIterator;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Similar to the {@link Configuration} object but handles EJB3 and Hibernate
+ * specific annotations as a metadata facility.
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+public class AnnotationConfiguration extends Configuration {
+ private Logger log = LoggerFactory.getLogger( AnnotationConfiguration.class );
+
+ /**
+ * Setting used to give the name of the default {@link
org.hibernate.annotations.CacheConcurrencyStrategy}
+ * to use when either {@link javax.persistence.Cacheable @Cacheable} or
+ * {@link Cache @Cache} is used. {@link Cache @Cache(strategy="..")} is used
to override.
+ */
+ public static final String DEFAULT_CACHE_CONCURRENCY_STRATEGY =
"hibernate.cache.default_cache_concurrency_strategy";
+
+ /**
+ * Setting which indicates whether or not the new {@link
org.hibernate.id.IdentifierGenerator} are used
+ * for AUTO, TABLE and SEQUENCE.
+ * Default to false to keep backward compatibility.
+ */
+ public static final String USE_NEW_ID_GENERATOR_MAPPINGS =
"hibernate.id.new_generator_mappings";
+
+ /**
+ * Class name of the class needed to enable Search.
+ */
+ private static final String SEARCH_STARTUP_CLASS =
"org.hibernate.search.event.EventListenerRegister";
+
+ /**
+ * Method to call to enable Search.
+ */
+ private static final String SEARCH_STARTUP_METHOD = "enableHibernateSearch";
+
+ public static final String ARTEFACT_PROCESSING_ORDER =
"hibernate.mapping.precedence";
+ public static final ConfigurationArtefactType[] DEFAULT_ARTEFACT_PROCESSING_ORDER =
+ new ConfigurationArtefactType[] { ConfigurationArtefactType.HBM,
ConfigurationArtefactType.CLASS };
+
+ private Map<String, IdGenerator> namedGenerators;
+ private Map<String, Map<String, Join>> joins;
+ private Map<String, AnnotatedClassType> classTypes;
+ private Set<String> defaultNamedQueryNames;
+ private Set<String> defaultNamedNativeQueryNames;
+ private Set<String> defaultSqlResulSetMappingNames;
+ private Set<String> defaultNamedGenerators;
+ private Map<String, Properties> generatorTables;
+ private Map<Table, List<UniqueConstraintHolder>>
uniqueConstraintHoldersByTable;
+ private Map<String, String> mappedByResolver;
+ private Map<String, String> propertyRefResolver;
+ private Map<String, AnyMetaDef> anyMetaDefs;
+ private List<XClass> annotatedClasses;
+ private Map<String, XClass> annotatedClassEntities;
+ private Map<String, Document> hbmEntities;
+ private List<CacheHolder> caches;
+ private List<Document> hbmDocuments; //user ordering matters, hence the list
+ private List<ConfigurationArtefactType> configurationArtefactPrecedence;
+ private boolean inSecondPass = false;
+ private transient ReflectionManager reflectionManager;
+ private boolean isDefaultProcessed = false;
+ private boolean isValidatorNotPresentLogged;
+ private Map<XClass, Map<String, PropertyData>>
propertiesAnnotatedWithMapsId;
+ private Map<XClass, Map<String, PropertyData>>
propertiesAnnotatedWithIdAndToOne;
+ private Collection<FetchProfile> annotationConfiguredProfiles;
+
+ public AnnotationConfiguration() {
+ super();
+ }
+
+ public AnnotationConfiguration(SettingsFactory sf) {
+ super( sf );
+ }
+
+ /**
+ * Takes the list of entities annotated with {@code @Entity} or {@code
@MappedSuperclass} and returns them in an
+ * ordered list.
+ *
+ * @param original The list of all entities annotated with {@code @Entity} or {@code
@MappedSuperclass}
+ *
+ * @return Ordered list of entities including superclasses for entities which have any.
Class hierachies are
+ * listed bottom up (starting from the top level base class). There is no
indication in the list when a new class
+ * (hierarchy) starts.
+ */
+ protected List<XClass> orderAndFillHierarchy(List<XClass> original) {
+ List<XClass> copy = new ArrayList<XClass>( original );
+ insertMappedSuperclasses( original, copy );
+
+ // order the hierarchy
+ List<XClass> workingCopy = new ArrayList<XClass>( copy );
+ List<XClass> newList = new ArrayList<XClass>( copy.size() );
+ while ( workingCopy.size() > 0 ) {
+ XClass clazz = workingCopy.get( 0 );
+ orderHierarchy( workingCopy, newList, copy, clazz );
+ }
+ return newList;
+ }
+
+ private void insertMappedSuperclasses(List<XClass> original, List<XClass>
copy) {
+ for ( XClass clazz : original ) {
+ XClass superClass = clazz.getSuperclass();
+ while ( superClass != null && !reflectionManager.equals( superClass,
Object.class ) && !copy.contains(
+ superClass
+ ) ) {
+ if ( superClass.isAnnotationPresent( Entity.class )
+ || superClass.isAnnotationPresent( MappedSuperclass.class ) ) {
+ copy.add( superClass );
+ }
+ superClass = superClass.getSuperclass();
+ }
+ }
+ }
+
+ private void orderHierarchy(List<XClass> copy, List<XClass> newList,
List<XClass> original, XClass clazz) {
+ if ( clazz == null || reflectionManager.equals( clazz, Object.class ) ) {
+ return;
+ }
+ //process superclass first
+ orderHierarchy( copy, newList, original, clazz.getSuperclass() );
+ if ( original.contains( clazz ) ) {
+ if ( !newList.contains( clazz ) ) {
+ newList.add( clazz );
+ }
+ copy.remove( clazz );
+ }
+ }
+
+ /**
+ * Read a mapping from the class annotation metadata (JSR 175).
+ *
+ * @param persistentClass the mapped class
+ *
+ * @return the configuration object
+ *
+ * @throws MappingException in case there is a configuration error for the specified
class
+ */
+ @SuppressWarnings({ "unchecked" })
+ public AnnotationConfiguration addAnnotatedClass(Class persistentClass) throws
MappingException {
+ XClass persistentXClass = reflectionManager.toXClass( persistentClass );
+ try {
+ annotatedClasses.add( persistentXClass );
+ return this;
+ }
+ catch ( MappingException me ) {
+ log.error( "Could not compile the mapping annotations", me );
+ throw me;
+ }
+ }
+
+ /**
+ * Read package level metadata.
+ *
+ * @param packageName java package name
+ *
+ * @return the configuration object
+ *
+ * @throws MappingException in case there is an error in the mapping data
+ */
+ public AnnotationConfiguration addPackage(String packageName) throws MappingException {
+ log.info( "Mapping package {}", packageName );
+ try {
+ AnnotationBinder.bindPackage( packageName, createExtendedMappings() );
+ return this;
+ }
+ catch ( MappingException me ) {
+ log.error( "Could not compile the mapping annotations", me );
+ throw me;
+ }
+ }
+
+ public ExtendedMappings createExtendedMappings() {
+ return new ExtendedMappingsImpl( annotationConfiguredProfiles );
+ }
+
+ @Override
+ public void setCacheConcurrencyStrategy(
+ String clazz, String concurrencyStrategy, String region, boolean cacheLazyProperty
+ ) throws MappingException {
+ caches.add( new CacheHolder( clazz, concurrencyStrategy, region, true,
cacheLazyProperty ) );
+ }
+
+ @Override
+ public void setCollectionCacheConcurrencyStrategy(String collectionRole, String
concurrencyStrategy, String region)
+ throws MappingException {
+ caches.add( new CacheHolder( collectionRole, concurrencyStrategy, region, false, false
) );
+ }
+
+ @Override
+ protected void reset() {
+ super.reset();
+ namedGenerators = new HashMap<String, IdGenerator>();
+ joins = new HashMap<String, Map<String, Join>>();
+ classTypes = new HashMap<String, AnnotatedClassType>();
+ generatorTables = new HashMap<String, Properties>();
+ defaultNamedQueryNames = new HashSet<String>();
+ defaultNamedNativeQueryNames = new HashSet<String>();
+ defaultSqlResulSetMappingNames = new HashSet<String>();
+ defaultNamedGenerators = new HashSet<String>();
+ uniqueConstraintHoldersByTable = new HashMap<Table,
List<UniqueConstraintHolder>>();
+ mappedByResolver = new HashMap<String, String>();
+ propertyRefResolver = new HashMap<String, String>();
+ annotatedClasses = new ArrayList<XClass>();
+ caches = new ArrayList<CacheHolder>();
+ hbmEntities = new HashMap<String, Document>();
+ annotatedClassEntities = new HashMap<String, XClass>();
+ hbmDocuments = new ArrayList<Document>();
+ namingStrategy = EJB3NamingStrategy.INSTANCE;
+ setEntityResolver( new EJB3DTDEntityResolver() );
+ anyMetaDefs = new HashMap<String, AnyMetaDef>();
+ propertiesAnnotatedWithMapsId = new HashMap<XClass, Map<String,
PropertyData>>();
+ propertiesAnnotatedWithIdAndToOne = new HashMap<XClass, Map<String,
PropertyData>>();
+ reflectionManager = new JavaReflectionManager();
+ ( ( MetadataProviderInjector ) reflectionManager ).setMetadataProvider( new
JPAMetadataProvider() );
+ configurationArtefactPrecedence = Collections.emptyList();
+ annotationConfiguredProfiles = new HashSet<FetchProfile>();
+ }
+
+ @Override
+ protected void secondPassCompile() throws MappingException {
+ log.debug( "Execute first pass mapping processing" );
+ //build annotatedClassEntities
+ {
+ List<XClass> tempAnnotatedClasses = new ArrayList<XClass>(
annotatedClasses.size() );
+ for ( XClass clazz : annotatedClasses ) {
+ if ( clazz.isAnnotationPresent( Entity.class ) ) {
+ annotatedClassEntities.put( clazz.getName(), clazz );
+ tempAnnotatedClasses.add( clazz );
+ }
+ else if ( clazz.isAnnotationPresent( MappedSuperclass.class ) ) {
+ tempAnnotatedClasses.add( clazz );
+ }
+ //only keep MappedSuperclasses and Entity in this list
+ }
+ annotatedClasses = tempAnnotatedClasses;
+ }
+
+ //process default values first
+ if ( !isDefaultProcessed ) {
+ //use global delimiters if orm.xml declare it
+ final Object isDelimited = reflectionManager.getDefaults().get(
"delimited-identifier" );
+ if ( isDelimited != null && isDelimited == Boolean.TRUE ) {
+ getProperties().put( Environment.GLOBALLY_QUOTED_IDENTIFIERS, "true" );
+ }
+
+ AnnotationBinder.bindDefaults( createExtendedMappings() );
+ isDefaultProcessed = true;
+ }
+
+ //process entities
+ if ( configurationArtefactPrecedence.isEmpty()
+ && StringHelper.isNotEmpty( getProperties().getProperty(
ARTEFACT_PROCESSING_ORDER ) ) ) {
+ configurationArtefactPrecedence = parsePrecedence( getProperties().getProperty(
ARTEFACT_PROCESSING_ORDER ) );
+ }
+ if ( configurationArtefactPrecedence.isEmpty() ) {
+ configurationArtefactPrecedence = Arrays.asList( DEFAULT_ARTEFACT_PROCESSING_ORDER );
+ }
+ configurationArtefactPrecedence = Collections.unmodifiableList(
configurationArtefactPrecedence );
+
+ for ( ConfigurationArtefactType p : configurationArtefactPrecedence ) {
+ removeConflictedArtifact( p );
+ processArtifactsOfType( p );
+ }
+
+ int cacheNbr = caches.size();
+ for ( int index = 0; index < cacheNbr; index++ ) {
+ CacheHolder cacheHolder = caches.get( index );
+ if ( cacheHolder.isClass ) {
+ super.setCacheConcurrencyStrategy(
+ cacheHolder.role, cacheHolder.usage, cacheHolder.region, cacheHolder.cacheLazy
+ );
+ }
+ else {
+ super.setCollectionCacheConcurrencyStrategy( cacheHolder.role, cacheHolder.usage,
cacheHolder.region );
+ }
+ }
+ caches.clear();
+ try {
+ inSecondPass = true;
+ processSecondPassesOfType( PkDrivenByDefaultMapsIdSecondPass.class );
+ processSecondPassesOfType( SetSimpleValueTypeSecondPass.class );
+ processSecondPassesOfType( CopyIdentifierComponentSecondPass.class );
+ processFkSecondPassInOrder();
+ processSecondPassesOfType( CreateKeySecondPass.class );
+ processSecondPassesOfType( SecondaryTableSecondPass.class );
+ super.secondPassCompile();
+ inSecondPass = false;
+ }
+ catch ( RecoverableException e ) {
+ //the exception was not recoverable after all
+ throw ( RuntimeException ) e.getCause();
+ }
+
+ for ( Map.Entry<Table, List<UniqueConstraintHolder>> tableListEntry :
uniqueConstraintHoldersByTable.entrySet() ) {
+ final Table table = tableListEntry.getKey();
+ final List<UniqueConstraintHolder> uniqueConstraints =
tableListEntry.getValue();
+ int uniqueIndexPerTable = 0;
+ for ( UniqueConstraintHolder holder : uniqueConstraints ) {
+ uniqueIndexPerTable++;
+ final String keyName = StringHelper.isEmpty( holder.getName() )
+ ? "key" + uniqueIndexPerTable
+ : holder.getName();
+ buildUniqueKeyFromColumnNames( table, keyName, holder.getColumns() );
+ }
+ }
+ applyConstraintsToDDL();
+ }
+
+ private void processSecondPassesOfType(Class<? extends SecondPass> type) {
+ Iterator iter = secondPasses.iterator();
+ while ( iter.hasNext() ) {
+ SecondPass sp = ( SecondPass ) iter.next();
+ //do the second pass of simple value types first and remove them
+ if ( type.isInstance( sp ) ) {
+ sp.doSecondPass( classes );
+ iter.remove();
+ }
+ }
+ }
+
+ private void applyConstraintsToDDL() {
+ boolean applyOnDdl = getProperties().getProperty(
+ "hibernate.validator.apply_to_ddl",
+ "true"
+ )
+ .equalsIgnoreCase( "true" );
+
+ if ( !applyOnDdl ) {
+ return; // nothing to do in this case
+ }
+ applyHibernateValidatorLegacyConstraintsOnDDL();
+ applyBeanValidationConstraintsOnDDL();
+ }
+
+ @SuppressWarnings({ "unchecked" })
+ private void applyHibernateValidatorLegacyConstraintsOnDDL() {
+ //TODO search for the method only once and cache it?
+ Constructor validatorCtr = null;
+ Method applyMethod = null;
+ try {
+ Class classValidator = ReflectHelper.classForName(
+ "org.hibernate.validator.ClassValidator", this.getClass()
+ );
+ Class messageInterpolator = ReflectHelper.classForName(
+ "org.hibernate.validator.MessageInterpolator", this.getClass()
+ );
+ validatorCtr = classValidator.getDeclaredConstructor(
+ Class.class, ResourceBundle.class, messageInterpolator, Map.class,
ReflectionManager.class
+ );
+ applyMethod = classValidator.getMethod( "apply", PersistentClass.class );
+ }
+ catch ( ClassNotFoundException e ) {
+ if ( !isValidatorNotPresentLogged ) {
+ log.info( "Hibernate Validator not found: ignoring" );
+ }
+ isValidatorNotPresentLogged = true;
+ }
+ catch ( NoSuchMethodException e ) {
+ throw new AnnotationException( e );
+ }
+ if ( applyMethod != null ) {
+ for ( PersistentClass persistentClazz : ( Collection<PersistentClass> )
classes.values() ) {
+ //integrate the validate framework
+ String className = persistentClazz.getClassName();
+ if ( StringHelper.isNotEmpty( className ) ) {
+ try {
+ Object validator = validatorCtr.newInstance(
+ ReflectHelper.classForName( className ), null, null, null, reflectionManager
+ );
+ applyMethod.invoke( validator, persistentClazz );
+ }
+ catch ( Exception e ) {
+ log.warn( "Unable to apply constraints on DDL for " + className, e );
+ }
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings({ "unchecked" })
+ private void applyBeanValidationConstraintsOnDDL() {
+ BeanValidationActivator.applyDDL( ( Collection<PersistentClass> )
classes.values(), getProperties() );
+ }
+
+ /**
+ * Processes FKSecondPass instances trying to resolve any
+ * graph circularity (ie PK made of a many to one linking to
+ * an entity having a PK made of a ManyToOne ...).
+ */
+ private void processFkSecondPassInOrder() {
+ log.debug( "processing fk mappings (*ToOne and JoinedSubclass)" );
+ List<FkSecondPass> fkSecondPasses = getFKSecondPassesOnly();
+
+ if ( fkSecondPasses.size() == 0 ) {
+ return; // nothing to do here
+ }
+
+ // split FkSecondPass instances into primary key and non primary key FKs.
+ // While doing so build a map of class names to FkSecondPass instances depending on
this class.
+ Map<String, Set<FkSecondPass>> isADependencyOf = new HashMap<String,
Set<FkSecondPass>>();
+ List<FkSecondPass> endOfQueueFkSecondPasses = new ArrayList<FkSecondPass>(
fkSecondPasses.size() );
+ for ( FkSecondPass sp : fkSecondPasses ) {
+ if ( sp.isInPrimaryKey() ) {
+ String referenceEntityName = sp.getReferencedEntityName();
+ PersistentClass classMapping = getClassMapping( referenceEntityName );
+ String dependentTable = classMapping.getTable().getQuotedName();
+ if ( !isADependencyOf.containsKey( dependentTable ) ) {
+ isADependencyOf.put( dependentTable, new HashSet<FkSecondPass>() );
+ }
+ isADependencyOf.get( dependentTable ).add( sp );
+ }
+ else {
+ endOfQueueFkSecondPasses.add( sp );
+ }
+ }
+
+ // using the isADependencyOf map we order the FkSecondPass recursively instances into
the right order for processing
+ List<FkSecondPass> orderedFkSecondPasses = new ArrayList<FkSecondPass>(
fkSecondPasses.size() );
+ for ( String tableName : isADependencyOf.keySet() ) {
+ buildRecursiveOrderedFkSecondPasses( orderedFkSecondPasses, isADependencyOf,
tableName, tableName );
+ }
+
+ // process the ordered FkSecondPasses
+ for ( FkSecondPass sp : orderedFkSecondPasses ) {
+ sp.doSecondPass( classes );
+ }
+
+ processEndOfQueue( endOfQueueFkSecondPasses );
+ }
+
+ private void processEndOfQueue(List<FkSecondPass> endOfQueueFkSecondPasses) {
+ /*
+ * If a second pass raises a recoverableException, queue it for next round
+ * stop of no pass has to be processed or if the number of pass to processes
+ * does not diminish between two rounds.
+ * If some failing pass remain, raise the original exception
+ */
+ boolean stopProcess = false;
+ RuntimeException originalException = null;
+ while ( !stopProcess ) {
+ List<FkSecondPass> failingSecondPasses = new ArrayList<FkSecondPass>();
+ Iterator<FkSecondPass> it = endOfQueueFkSecondPasses.listIterator();
+ while ( it.hasNext() ) {
+ final FkSecondPass pass = it.next();
+ try {
+ pass.doSecondPass( classes );
+ }
+ catch ( RecoverableException e ) {
+ failingSecondPasses.add( pass );
+ if ( originalException == null ) {
+ originalException = ( RuntimeException ) e.getCause();
+ }
+ }
+ }
+ stopProcess = failingSecondPasses.size() == 0 || failingSecondPasses.size() ==
endOfQueueFkSecondPasses.size();
+ endOfQueueFkSecondPasses = failingSecondPasses;
+ }
+ if ( endOfQueueFkSecondPasses.size() > 0 ) {
+ throw originalException;
+ }
+ }
+
+ /**
+ * @return Returns a list of all <code>secondPasses</code> instances which
are a instance of
+ * <code>FkSecondPass</code>.
+ */
+ private List<FkSecondPass> getFKSecondPassesOnly() {
+ Iterator iter = secondPasses.iterator();
+ List<FkSecondPass> fkSecondPasses = new ArrayList<FkSecondPass>(
secondPasses.size() );
+ while ( iter.hasNext() ) {
+ SecondPass sp = ( SecondPass ) iter.next();
+ //do the second pass of fk before the others and remove them
+ if ( sp instanceof FkSecondPass ) {
+ fkSecondPasses.add( ( FkSecondPass ) sp );
+ iter.remove();
+ }
+ }
+ return fkSecondPasses;
+ }
+
+ /**
+ * Recursively builds a list of FkSecondPass instances ready to be processed in this
order.
+ * Checking all dependencies recursively seems quite expensive, but the original code
just relied
+ * on some sort of table name sorting which failed in certain circumstances.
+ * <p/>
+ * See <tt>ANN-722</tt> and <tt>ANN-730</tt>
+ *
+ * @param orderedFkSecondPasses The list containing the
<code>FkSecondPass<code> instances ready
+ * for processing.
+ * @param isADependencyOf Our lookup data structure to determine dependencies between
tables
+ * @param startTable Table name to start recursive algorithm.
+ * @param currentTable The current table name used to check for 'new'
dependencies.
+ */
+ private void buildRecursiveOrderedFkSecondPasses(
+ List<FkSecondPass> orderedFkSecondPasses,
+ Map<String, Set<FkSecondPass>> isADependencyOf,
+ String startTable,
+ String currentTable) {
+
+ Set<FkSecondPass> dependencies = isADependencyOf.get( currentTable );
+
+ // bottom out
+ if ( dependencies == null || dependencies.size() == 0 ) {
+ return;
+ }
+
+ for ( FkSecondPass sp : dependencies ) {
+ String dependentTable = sp.getValue().getTable().getQuotedName();
+ if ( dependentTable.compareTo( startTable ) == 0 ) {
+ StringBuilder sb = new StringBuilder(
+ "Foreign key circularity dependency involving the following tables: "
+ );
+ throw new AnnotationException( sb.toString() );
+ }
+ buildRecursiveOrderedFkSecondPasses( orderedFkSecondPasses, isADependencyOf,
startTable, dependentTable );
+ if ( !orderedFkSecondPasses.contains( sp ) ) {
+ orderedFkSecondPasses.add( 0, sp );
+ }
+ }
+ }
+
+ private void processArtifactsOfType(ConfigurationArtefactType p) {
+ if ( ConfigurationArtefactType.HBM.equals( p ) ) {
+ log.debug( "Process hbm files" );
+ for ( Document document : hbmDocuments ) {
+ super.add( document );
+ }
+ hbmDocuments.clear();
+ hbmEntities.clear();
+ }
+ else if ( ConfigurationArtefactType.CLASS.equals( p ) ) {
+ log.debug( "Process annotated classes" );
+ //bind classes in the correct order calculating some inheritance state
+ List<XClass> orderedClasses = orderAndFillHierarchy( annotatedClasses );
+ ExtendedMappings mappings = createExtendedMappings();
+ Map<XClass, InheritanceState> inheritanceStatePerClass =
AnnotationBinder.buildInheritanceStates(
+ orderedClasses, mappings
+ );
+
+
+ for ( XClass clazz : orderedClasses ) {
+ //todo use the same extended mapping
+ AnnotationBinder.bindClass( clazz, inheritanceStatePerClass, mappings );
+ }
+ annotatedClasses.clear();
+ annotatedClassEntities.clear();
+ }
+ }
+
+ private void removeConflictedArtifact(ConfigurationArtefactType p) {
+ if ( ConfigurationArtefactType.HBM.equals( p ) ) {
+ for ( String entity : hbmEntities.keySet() ) {
+ if ( annotatedClassEntities.containsKey( entity ) ) {
+ annotatedClasses.remove( annotatedClassEntities.get( entity ) );
+ annotatedClassEntities.remove( entity );
+ }
+ }
+ }
+ else if ( ConfigurationArtefactType.CLASS.equals( p ) ) {
+ for ( String entity : annotatedClassEntities.keySet() ) {
+ if ( hbmEntities.containsKey( entity ) ) {
+ hbmDocuments.remove( hbmEntities.get( entity ) );
+ hbmEntities.remove( entity );
+ }
+ }
+ }
+ }
+
+ private void buildUniqueKeyFromColumnNames(Table table, String keyName, String[]
columnNames) {
+ ExtendedMappings mappings = createExtendedMappings();
+ keyName = mappings.getObjectNameNormalizer().normalizeIdentifierQuoting( keyName );
+
+ UniqueKey uc;
+ int size = columnNames.length;
+ Column[] columns = new Column[size];
+ Set<Column> unbound = new HashSet<Column>();
+ Set<Column> unboundNoLogical = new HashSet<Column>();
+ for ( int index = 0; index < size; index++ ) {
+ final String logicalColumnName = mappings.getObjectNameNormalizer()
+ .normalizeIdentifierQuoting( columnNames[index] );
+ try {
+ final String columnName = mappings.getPhysicalColumnName( logicalColumnName, table
);
+ columns[index] = new Column( columnName );
+ unbound.add( columns[index] );
+ //column equals and hashcode is based on column name
+ }
+ catch ( MappingException e ) {
+ unboundNoLogical.add( new Column( logicalColumnName ) );
+ }
+ }
+ for ( Column column : columns ) {
+ if ( table.containsColumn( column ) ) {
+ uc = table.getOrCreateUniqueKey( keyName );
+ uc.addColumn( table.getColumn( column ) );
+ unbound.remove( column );
+ }
+ }
+ if ( unbound.size() > 0 || unboundNoLogical.size() > 0 ) {
+ StringBuilder sb = new StringBuilder( "Unable to create unique key constraint
(" );
+ for ( String columnName : columnNames ) {
+ sb.append( columnName ).append( ", " );
+ }
+ sb.setLength( sb.length() - 2 );
+ sb.append( ") on table " ).append( table.getName() ).append( ": "
);
+ for ( Column column : unbound ) {
+ sb.append( column.getName() ).append( ", " );
+ }
+ for ( Column column : unboundNoLogical ) {
+ sb.append( column.getName() ).append( ", " );
+ }
+ sb.setLength( sb.length() - 2 );
+ sb.append( " not found" );
+ throw new AnnotationException( sb.toString() );
+ }
+ }
+
+ @Override
+ protected void parseMappingElement(Element subelement, String name) {
+ Attribute rsrc = subelement.attribute( "resource" );
+ Attribute file = subelement.attribute( "file" );
+ Attribute jar = subelement.attribute( "jar" );
+ Attribute pckg = subelement.attribute( "package" );
+ Attribute clazz = subelement.attribute( "class" );
+ if ( rsrc != null ) {
+ log.debug( "{} <- {}", name, rsrc );
+ addResource( rsrc.getValue() );
+ }
+ else if ( jar != null ) {
+ log.debug( "{} <- {}", name, jar );
+ addJar( new File( jar.getValue() ) );
+ }
+ else if ( file != null ) {
+ log.debug( "{} <- {}", name, file );
+ addFile( file.getValue() );
+ }
+ else if ( pckg != null ) {
+ log.debug( "{} <- {}", name, pckg );
+ addPackage( pckg.getValue() );
+ }
+ else if ( clazz != null ) {
+ log.debug( "{} <- {}", name, clazz );
+ Class loadedClass;
+ try {
+ loadedClass = ReflectHelper.classForName( clazz.getValue() );
+ }
+ catch ( ClassNotFoundException cnf ) {
+ throw new MappingException(
+ "Unable to load class declared as <mapping class=\"" +
clazz.getValue() + "\"/> in the configuration:",
+ cnf
+ );
+ }
+ catch ( NoClassDefFoundError ncdf ) {
+ throw new MappingException(
+ "Unable to load class declared as <mapping class=\"" +
clazz.getValue() + "\"/> in the configuration:",
+ ncdf
+ );
+ }
+
+ addAnnotatedClass( loadedClass );
+ }
+ else {
+ throw new MappingException( "<mapping> element in configuration specifies
no attributes" );
+ }
+ }
+
+ @Override
+ protected void add(org.dom4j.Document doc) throws MappingException {
+ boolean ejb3Xml = "entity-mappings".equals( doc.getRootElement().getName()
);
+ if ( inSecondPass ) {
+ //if in second pass bypass the queueing, getExtendedQueue reuse this method
+ if ( !ejb3Xml ) {
+ super.add( doc );
+ }
+ }
+ else {
+ if ( !ejb3Xml ) {
+ final Element hmNode = doc.getRootElement();
+ Attribute packNode = hmNode.attribute( "package" );
+ String defaultPackage = packNode != null
+ ? packNode.getValue()
+ : "";
+ Set<String> entityNames = new HashSet<String>();
+ findClassNames( defaultPackage, hmNode, entityNames );
+ for ( String entity : entityNames ) {
+ hbmEntities.put( entity, doc );
+ }
+ hbmDocuments.add( doc );
+ }
+ else {
+ final MetadataProvider metadataProvider = ( ( MetadataProviderInjector )
reflectionManager ).getMetadataProvider();
+ JPAMetadataProvider jpaMetadataProvider = ( JPAMetadataProvider ) metadataProvider;
+ List<String> classnames = jpaMetadataProvider.getXMLContext().addDocument( doc
);
+ for ( String classname : classnames ) {
+ try {
+ annotatedClasses.add( reflectionManager.classForName( classname, this.getClass() )
);
+ }
+ catch ( ClassNotFoundException e ) {
+ throw new AnnotationException( "Unable to load class defined in XML: " +
classname, e );
+ }
+ }
+ }
+ }
+ }
+
+ private static void findClassNames(
+ String defaultPackage, final Element startNode,
+ final java.util.Set<String> names
+ ) {
+ // if we have some extends we need to check if those classes possibly could be inside
the
+ // same hbm.xml file...
+ Iterator[] classes = new Iterator[4];
+ classes[0] = startNode.elementIterator( "class" );
+ classes[1] = startNode.elementIterator( "subclass" );
+ classes[2] = startNode.elementIterator( "joined-subclass" );
+ classes[3] = startNode.elementIterator( "union-subclass" );
+
+ Iterator classIterator = new JoinedIterator( classes );
+ while ( classIterator.hasNext() ) {
+ Element element = ( Element ) classIterator.next();
+ String entityName = element.attributeValue( "entity-name" );
+ if ( entityName == null ) {
+ entityName = getClassName( element.attribute( "name" ), defaultPackage );
+ }
+ names.add( entityName );
+ findClassNames( defaultPackage, element, names );
+ }
+ }
+
+ private static String getClassName(Attribute name, String defaultPackage) {
+ if ( name == null ) {
+ return null;
+ }
+ String unqualifiedName = name.getValue();
+ if ( unqualifiedName == null ) {
+ return null;
+ }
+ if ( unqualifiedName.indexOf( '.' ) < 0 && defaultPackage != null )
{
+ return defaultPackage + '.' + unqualifiedName;
+ }
+ return unqualifiedName;
+ }
+
+ public void setPrecedence(String precedence) {
+ this.configurationArtefactPrecedence = parsePrecedence( precedence );
+ }
+
+ private List<ConfigurationArtefactType> parsePrecedence(String s) {
+ if ( StringHelper.isEmpty( s ) ) {
+ return Collections.emptyList();
+ }
+ StringTokenizer precedences = new StringTokenizer( s, ",; ", false );
+ List<ConfigurationArtefactType> tmpPrecedences = new
ArrayList<ConfigurationArtefactType>();
+ while ( precedences.hasMoreElements() ) {
+ tmpPrecedences.add( ConfigurationArtefactType.parsePrecedence( ( String )
precedences.nextElement() ) );
+ }
+ return tmpPrecedences;
+ }
+
+ @Override
+ public AnnotationConfiguration addInputStream(InputStream xmlInputStream) throws
MappingException {
+ try {
+ /*
+ * try and parse the document:
+ * - try and validate the document with orm_2_0.xsd
+ * - if it fails because of the version attribute mismatch, try and validate the
document with orm_1_0.xsd
+ */
+ List<SAXParseException> errors = new ArrayList<SAXParseException>();
+ SAXReader saxReader = new SAXReader();
+ saxReader.setEntityResolver( getEntityResolver() );
+ saxReader.setErrorHandler( new ErrorLogger( errors ) );
+ saxReader.setMergeAdjacentText( true );
+ saxReader.setValidation( true );
+
+ setValidationFor( saxReader, "orm_2_0.xsd" );
+
+ org.dom4j.Document doc = null;
+ try {
+ doc = saxReader.read( new InputSource( xmlInputStream ) );
+ }
+ catch ( DocumentException e ) {
+ //the document is syntactically incorrect
+
+ //DOM4J sometimes wraps the SAXParseException wo much interest
+ final Throwable throwable = e.getCause();
+ if ( e.getCause() == null || !( throwable instanceof SAXParseException ) ) {
+ throw new MappingException( "Could not parse JPA mapping document", e );
+ }
+ errors.add( ( SAXParseException ) throwable );
+ }
+
+ boolean isV1Schema = false;
+ if ( errors.size() != 0 ) {
+ SAXParseException exception = errors.get( 0 );
+ final String errorMessage = exception.getMessage();
+ //does the error look like a schema mismatch?
+ isV1Schema = doc != null
+ && errorMessage.contains( "1.0" )
+ && errorMessage.contains( "2.0" )
+ && errorMessage.contains( "version" );
+ }
+ if ( isV1Schema ) {
+ //reparse with v1
+ errors.clear();
+ setValidationFor( saxReader, "orm_1_0.xsd" );
+ try {
+ //too bad we have to reparse to validate again :(
+ saxReader.read( new StringReader( doc.asXML() ) );
+ }
+ catch ( DocumentException e ) {
+ //oops asXML fails even if the core doc parses initially
+ throw new AssertionFailure( "Error in DOM4J leads to a bug in Hibernate",
e );
+ }
+
+ }
+ if ( errors.size() != 0 ) {
+ //report errors in exception
+ StringBuilder errorMessage = new StringBuilder();
+ for ( SAXParseException error : errors ) {
+ errorMessage.append( "Error parsing XML (line" )
+ .append( error.getLineNumber() )
+ .append( " : column " )
+ .append( error.getColumnNumber() )
+ .append( "): " )
+ .append( error.getMessage() )
+ .append( "\n" );
+ }
+ throw new MappingException( "Invalid ORM mapping file.\n" +
errorMessage.toString() );
+ }
+ add( doc );
+ return this;
+ }
+ finally {
+ try {
+ xmlInputStream.close();
+ }
+ catch ( IOException ioe ) {
+ log.warn( "Could not close input stream", ioe );
+ }
+ }
+ }
+
+ private void setValidationFor(SAXReader saxReader, String xsd) {
+ try {
+ saxReader.setFeature( "http://apache.org/xml/features/validation/schema",
true );
+ //saxReader.setFeature( "http://apache.org/xml/features/validation/dynamic",
true );
+ //set the default schema locators
+ saxReader.setProperty(
+ "http://apache.org/xml/properties/schema/external-schemaLocation",
+ "http://java.sun.com/xml/ns/persistence/orm " + xsd
+ );
+ }
+ catch ( SAXException e ) {
+ saxReader.setValidation( false );
+ }
+ }
+
+ public SessionFactory buildSessionFactory() throws HibernateException {
+ enableLegacyHibernateValidator();
+ enableBeanValidation();
+ enableHibernateSearch();
+ return super.buildSessionFactory();
+ }
+
+ private void enableLegacyHibernateValidator() {
+ //add validator events if the jar is available
+ boolean enableValidatorListeners = !"false".equalsIgnoreCase(
+ getProperty(
+ "hibernate.validator.autoregister_listeners"
+ )
+ );
+ Class validateEventListenerClass = null;
+ try {
+ validateEventListenerClass = ReflectHelper.classForName(
+ "org.hibernate.validator.event.ValidateEventListener",
+ AnnotationConfiguration.class
+ );
+ }
+ catch ( ClassNotFoundException e ) {
+ //validator is not present
+ log.debug( "Legacy Validator not present in classpath, ignoring event listener
registration" );
+ }
+ if ( enableValidatorListeners && validateEventListenerClass != null ) {
+ //TODO so much duplication
+ Object validateEventListener;
+ try {
+ validateEventListener = validateEventListenerClass.newInstance();
+ }
+ catch ( Exception e ) {
+ throw new AnnotationException( "Unable to load Validator event listener", e
);
+ }
+ {
+ boolean present = false;
+ PreInsertEventListener[] listeners =
getEventListeners().getPreInsertEventListeners();
+ if ( listeners != null ) {
+ for ( Object eventListener : listeners ) {
+ //not isAssignableFrom since the user could subclass
+ present = present || validateEventListenerClass == eventListener.getClass();
+ }
+ if ( !present ) {
+ int length = listeners.length + 1;
+ PreInsertEventListener[] newListeners = new PreInsertEventListener[length];
+ System.arraycopy( listeners, 0, newListeners, 0, length - 1 );
+ newListeners[length - 1] = ( PreInsertEventListener ) validateEventListener;
+ getEventListeners().setPreInsertEventListeners( newListeners );
+ }
+ }
+ else {
+ getEventListeners().setPreInsertEventListeners(
+ new PreInsertEventListener[] { ( PreInsertEventListener ) validateEventListener }
+ );
+ }
+ }
+
+ //update event listener
+ {
+ boolean present = false;
+ PreUpdateEventListener[] listeners =
getEventListeners().getPreUpdateEventListeners();
+ if ( listeners != null ) {
+ for ( Object eventListener : listeners ) {
+ //not isAssignableFrom since the user could subclass
+ present = present || validateEventListenerClass == eventListener.getClass();
+ }
+ if ( !present ) {
+ int length = listeners.length + 1;
+ PreUpdateEventListener[] newListeners = new PreUpdateEventListener[length];
+ System.arraycopy( listeners, 0, newListeners, 0, length - 1 );
+ newListeners[length - 1] = ( PreUpdateEventListener ) validateEventListener;
+ getEventListeners().setPreUpdateEventListeners( newListeners );
+ }
+ }
+ else {
+ getEventListeners().setPreUpdateEventListeners(
+ new PreUpdateEventListener[] { ( PreUpdateEventListener ) validateEventListener }
+ );
+ }
+ }
+ }
+ }
+
+ private void enableBeanValidation() {
+ BeanValidationActivator.activateBeanValidation( getEventListeners(), getProperties()
);
+ }
+
+ /**
+ * Tries to automatically register Hibernate Search event listeners by locating the
+ * appropriate bootstrap class and calling the
<code>enableHibernateSearch</code> method.
+ */
+ private void enableHibernateSearch() {
+ // load the bootstrap class
+ Class searchStartupClass;
+ try {
+ searchStartupClass = ReflectHelper.classForName( SEARCH_STARTUP_CLASS,
AnnotationConfiguration.class );
+ }
+ catch ( ClassNotFoundException e ) {
+ // TODO remove this together with SearchConfiguration after 3.1.0 release of Search
+ // try loading deprecated HibernateSearchEventListenerRegister
+ try {
+ searchStartupClass = ReflectHelper.classForName(
+ "org.hibernate.cfg.search.HibernateSearchEventListenerRegister",
AnnotationConfiguration.class
+ );
+ }
+ catch ( ClassNotFoundException cnfe ) {
+ log.debug( "Search not present in classpath, ignoring event listener
registration." );
+ return;
+ }
+ }
+
+ // call the method for registering the listeners
+ try {
+ Object searchStartupInstance = searchStartupClass.newInstance();
+ Method enableSearchMethod = searchStartupClass.getDeclaredMethod(
+ SEARCH_STARTUP_METHOD,
+ EventListeners.class, Properties.class
+ );
+ enableSearchMethod.invoke( searchStartupInstance, getEventListeners(), getProperties()
);
+ }
+ catch ( InstantiationException e ) {
+ log.debug( "Unable to instantiate {}, ignoring event listener
registration.", SEARCH_STARTUP_CLASS );
+ }
+ catch ( IllegalAccessException e ) {
+ log.debug( "Unable to instantiate {}, ignoring event listener
registration.", SEARCH_STARTUP_CLASS );
+ }
+ catch ( NoSuchMethodException e ) {
+ log.debug( "Method enableHibernateSearch() not found in {}.",
SEARCH_STARTUP_CLASS );
+ }
+ catch ( InvocationTargetException e ) {
+ log.debug( "Unable to execute {}, ignoring event listener registration.",
SEARCH_STARTUP_METHOD );
+ }
+ }
+
+ @Override
+ public AnnotationConfiguration addFile(String xmlFile) throws MappingException {
+ super.addFile( xmlFile );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration addFile(File xmlFile) throws MappingException {
+ super.addFile( xmlFile );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration addCacheableFile(File xmlFile) throws MappingException {
+ super.addCacheableFile( xmlFile );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration addCacheableFile(String xmlFile) throws MappingException
{
+ super.addCacheableFile( xmlFile );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration addXML(String xml) throws MappingException {
+ super.addXML( xml );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration addURL(URL url) throws MappingException {
+ super.addURL( url );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration addResource(String resourceName, ClassLoader classLoader)
throws MappingException {
+ super.addResource( resourceName, classLoader );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration addDocument(org.w3c.dom.Document doc) throws
MappingException {
+ super.addDocument( doc );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration addResource(String resourceName) throws MappingException
{
+ super.addResource( resourceName );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration addClass(Class persistentClass) throws MappingException
{
+ super.addClass( persistentClass );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration addJar(File jar) throws MappingException {
+ super.addJar( jar );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration addDirectory(File dir) throws MappingException {
+ super.addDirectory( dir );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration setInterceptor(Interceptor interceptor) {
+ super.setInterceptor( interceptor );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration setProperties(Properties properties) {
+ super.setProperties( properties );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration addProperties(Properties extraProperties) {
+ super.addProperties( extraProperties );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration mergeProperties(Properties properties) {
+ super.mergeProperties( properties );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration setProperty(String propertyName, String value) {
+ super.setProperty( propertyName, value );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration configure() throws HibernateException {
+ super.configure();
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration configure(String resource) throws HibernateException {
+ super.configure( resource );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration configure(URL url) throws HibernateException {
+ super.configure( url );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration configure(File configFile) throws HibernateException {
+ super.configure( configFile );
+ return this;
+ }
+
+ @Override
+ protected AnnotationConfiguration doConfigure(InputStream stream, String resourceName)
throws HibernateException {
+ super.doConfigure( stream, resourceName );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration configure(org.w3c.dom.Document document) throws
HibernateException {
+ super.configure( document );
+ return this;
+ }
+
+ @Override
+ protected AnnotationConfiguration doConfigure(Document doc) throws HibernateException {
+ super.doConfigure( doc );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration setCacheConcurrencyStrategy(String clazz, String
concurrencyStrategy)
+ throws MappingException {
+ super.setCacheConcurrencyStrategy( clazz, concurrencyStrategy );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration setCollectionCacheConcurrencyStrategy(String
collectionRole, String concurrencyStrategy)
+ throws MappingException {
+ super.setCollectionCacheConcurrencyStrategy( collectionRole, concurrencyStrategy );
+ return this;
+ }
+
+ @Override
+ public AnnotationConfiguration setNamingStrategy(NamingStrategy namingStrategy) {
+ super.setNamingStrategy( namingStrategy );
+ return this;
+ }
+
+ //not a public API
+
+ public ReflectionManager getReflectionManager() {
+ return reflectionManager;
+ }
+
+ protected class ExtendedMappingsImpl extends MappingsImpl implements ExtendedMappings {
+ private Boolean useNewGeneratorMappings;
+ private Collection<FetchProfile> annotationConfiguredProfile;
+
+ public ExtendedMappingsImpl(Collection<FetchProfile> fetchProfiles) {
+ annotationConfiguredProfile = fetchProfiles;
+ }
+
+ public void addDefaultGenerator(IdGenerator generator) {
+ this.addGenerator( generator );
+ defaultNamedGenerators.add( generator.getName() );
+ }
+
+ public boolean isInSecondPass() {
+ return inSecondPass;
+ }
+
+ public PropertyData getPropertyAnnotatedWithMapsId(XClass entityType, String
propertyName) {
+ final Map<String, PropertyData> map = propertiesAnnotatedWithMapsId.get(
entityType );
+ return map == null ? null : map.get( propertyName );
+ }
+
+ public void addPropertyAnnotatedWithMapsId(XClass entityType, PropertyData property) {
+ Map<String, PropertyData> map = propertiesAnnotatedWithMapsId.get( entityType
);
+ if ( map == null ) {
+ map = new HashMap<String, PropertyData>();
+ propertiesAnnotatedWithMapsId.put( entityType, map );
+ }
+ map.put( property.getProperty().getAnnotation( MapsId.class ).value(), property );
+ }
+
+ public PropertyData getPropertyAnnotatedWithIdAndToOne(XClass entityType, String
propertyName) {
+ final Map<String, PropertyData> map = propertiesAnnotatedWithIdAndToOne.get(
entityType );
+ return map == null ? null : map.get( propertyName );
+ }
+
+ public void addToOneAndIdProperty(XClass entityType, PropertyData property) {
+ Map<String, PropertyData> map = propertiesAnnotatedWithIdAndToOne.get(
entityType );
+ if ( map == null ) {
+ map = new HashMap<String, PropertyData>();
+ propertiesAnnotatedWithIdAndToOne.put( entityType, map );
+ }
+ map.put( property.getPropertyName(), property );
+ }
+
+ @SuppressWarnings({ "UnnecessaryUnboxing" })
+ public boolean useNewGeneratorMappings() {
+ if ( useNewGeneratorMappings == null ) {
+ final String booleanName = getConfigurationProperties().getProperty(
USE_NEW_ID_GENERATOR_MAPPINGS );
+ useNewGeneratorMappings = Boolean.valueOf( booleanName );
+ }
+ return useNewGeneratorMappings.booleanValue();
+ }
+
+ public IdGenerator getGenerator(String name) {
+ return getGenerator( name, null );
+ }
+
+ public IdGenerator getGenerator(String name, Map<String, IdGenerator>
localGenerators) {
+ if ( localGenerators != null ) {
+ IdGenerator result = localGenerators.get( name );
+ if ( result != null ) {
+ return result;
+ }
+ }
+ return namedGenerators.get( name );
+ }
+
+ public void addGenerator(IdGenerator generator) {
+ if ( !defaultNamedGenerators.contains( generator.getName() ) ) {
+ IdGenerator old = namedGenerators.put( generator.getName(), generator );
+ if ( old != null ) {
+ log.warn( "duplicate generator name {}", old.getName() );
+ }
+ }
+ }
+
+ public void addGeneratorTable(String name, Properties params) {
+ Object old = generatorTables.put( name, params );
+ if ( old != null ) {
+ log.warn( "duplicate generator table: {}", name );
+ }
+ }
+
+ public Properties getGeneratorTableProperties(String name, Map<String,
Properties> localGeneratorTables) {
+ if ( localGeneratorTables != null ) {
+ Properties result = localGeneratorTables.get( name );
+ if ( result != null ) {
+ return result;
+ }
+ }
+ return generatorTables.get( name );
+ }
+
+ public Map<String, Join> getJoins(String entityName) {
+ return joins.get( entityName );
+ }
+
+ public void addJoins(PersistentClass persistentClass, Map<String, Join> joins) {
+ Object old = AnnotationConfiguration.this.joins.put( persistentClass.getEntityName(),
joins );
+ if ( old != null ) {
+ log.warn( "duplicate joins for class: {}", persistentClass.getEntityName()
);
+ }
+ }
+
+ public AnnotatedClassType getClassType(XClass clazz) {
+ AnnotatedClassType type = classTypes.get( clazz.getName() );
+ if ( type == null ) {
+ return addClassType( clazz );
+ }
+ else {
+ return type;
+ }
+ }
+
+ //FIXME should be private but is part of the ExtendedMapping contract
+
+ public AnnotatedClassType addClassType(XClass clazz) {
+ AnnotatedClassType type;
+ if ( clazz.isAnnotationPresent( Entity.class ) ) {
+ type = AnnotatedClassType.ENTITY;
+ }
+ else if ( clazz.isAnnotationPresent( Embeddable.class ) ) {
+ type = AnnotatedClassType.EMBEDDABLE;
+ }
+ else if ( clazz.isAnnotationPresent( MappedSuperclass.class ) ) {
+ type = AnnotatedClassType.EMBEDDABLE_SUPERCLASS;
+ }
+ else {
+ type = AnnotatedClassType.NONE;
+ }
+ classTypes.put( clazz.getName(), type );
+ return type;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Map<Table, List<String[]>> getTableUniqueConstraints() {
+ final Map<Table, List<String[]>> deprecatedStructure = new
HashMap<Table, List<String[]>>(
+ CollectionHelper.determineProperSizing( getUniqueConstraintHoldersByTable() ),
+ CollectionHelper.LOAD_FACTOR
+ );
+ for ( Map.Entry<Table, List<UniqueConstraintHolder>> entry :
getUniqueConstraintHoldersByTable().entrySet() ) {
+ List<String[]> columnsPerConstraint = new ArrayList<String[]>(
+ CollectionHelper.determineProperSizing( entry.getValue().size() )
+ );
+ deprecatedStructure.put( entry.getKey(), columnsPerConstraint );
+ for ( UniqueConstraintHolder holder : entry.getValue() ) {
+ columnsPerConstraint.add( holder.getColumns() );
+ }
+ }
+ return deprecatedStructure;
+ }
+
+ public Map<Table, List<UniqueConstraintHolder>>
getUniqueConstraintHoldersByTable() {
+ return uniqueConstraintHoldersByTable;
+ }
+
+ @SuppressWarnings({ "unchecked" })
+ public void addUniqueConstraints(Table table, List uniqueConstraints) {
+ List<UniqueConstraintHolder> constraintHolders = new
ArrayList<UniqueConstraintHolder>(
+ CollectionHelper.determineProperSizing( uniqueConstraints.size() )
+ );
+
+ int keyNameBase = determineCurrentNumberOfUniqueConstraintHolders( table );
+ for ( String[] columns : ( List<String[]> ) uniqueConstraints ) {
+ final String keyName = "key" + keyNameBase++;
+ constraintHolders.add(
+ new UniqueConstraintHolder().setName( keyName ).setColumns( columns )
+ );
+ }
+ addUniqueConstraintHolders( table, constraintHolders );
+ }
+
+ private int determineCurrentNumberOfUniqueConstraintHolders(Table table) {
+ List currentHolders = getUniqueConstraintHoldersByTable().get( table );
+ return currentHolders == null
+ ? 0
+ : currentHolders.size();
+ }
+
+ public void addUniqueConstraintHolders(Table table, List<UniqueConstraintHolder>
uniqueConstraintHolders) {
+ List<UniqueConstraintHolder> holderList =
getUniqueConstraintHoldersByTable().get( table );
+ if ( holderList == null ) {
+ holderList = new ArrayList<UniqueConstraintHolder>();
+ getUniqueConstraintHoldersByTable().put( table, holderList );
+ }
+ holderList.addAll( uniqueConstraintHolders );
+ }
+
+ public void addMappedBy(String entityName, String propertyName, String
inversePropertyName) {
+ mappedByResolver.put( entityName + "." + propertyName, inversePropertyName
);
+ }
+
+ public String getFromMappedBy(String entityName, String propertyName) {
+ return mappedByResolver.get( entityName + "." + propertyName );
+ }
+
+ public void addPropertyReferencedAssociation(String entityName, String propertyName,
String propertyRef) {
+ propertyRefResolver.put( entityName + "." + propertyName, propertyRef );
+ }
+
+ public String getPropertyReferencedAssociation(String entityName, String propertyName)
{
+ return propertyRefResolver.get( entityName + "." + propertyName );
+ }
+
+ @Override
+ public void addUniquePropertyReference(String referencedClass, String propertyName) {
+ super.addUniquePropertyReference( referencedClass, propertyName );
+ }
+
+ @Override
+ public void addPropertyReference(String referencedClass, String propertyName) {
+ super.addPropertyReference( referencedClass, propertyName );
+ }
+
+ public ReflectionManager getReflectionManager() {
+ return reflectionManager;
+ }
+
+ public void addDefaultQuery(String name, NamedQueryDefinition query) {
+ super.addQuery( name, query );
+ defaultNamedQueryNames.add( name );
+ }
+
+ public void addDefaultSQLQuery(String name, NamedSQLQueryDefinition query) {
+ super.addSQLQuery( name, query );
+ defaultNamedNativeQueryNames.add( name );
+ }
+
+ public void addDefaultResultSetMapping(ResultSetMappingDefinition definition) {
+ final String name = definition.getName();
+ if ( !defaultSqlResulSetMappingNames.contains( name )
+ && super.getResultSetMapping( name ) != null ) {
+ removeResultSetMapping( name );
+ }
+ super.addResultSetMapping( definition );
+ defaultSqlResulSetMappingNames.add( name );
+ }
+
+ @Override
+ public void addQuery(String name, NamedQueryDefinition query) throws
DuplicateMappingException {
+ if ( !defaultNamedQueryNames.contains( name ) ) {
+ super.addQuery( name, query );
+ }
+ }
+
+ @Override
+ public void addResultSetMapping(ResultSetMappingDefinition definition) throws
DuplicateMappingException {
+ if ( !defaultSqlResulSetMappingNames.contains( definition.getName() ) ) {
+ super.addResultSetMapping( definition );
+ }
+ }
+
+ @Override
+ public void addSQLQuery(String name, NamedSQLQueryDefinition query) throws
DuplicateMappingException {
+ if ( !defaultNamedNativeQueryNames.contains( name ) ) {
+ super.addSQLQuery( name, query );
+ }
+ }
+
+ public Map getClasses() {
+ return classes;
+ }
+
+ public void addAnyMetaDef(AnyMetaDef defAnn) throws AnnotationException {
+ if ( anyMetaDefs.containsKey( defAnn.name() ) ) {
+ throw new AnnotationException( "Two @AnyMetaDef with the same name defined:
" + defAnn.name() );
+ }
+ anyMetaDefs.put( defAnn.name(), defAnn );
+ }
+
+ public AnyMetaDef getAnyMetaDef(String name) {
+ return anyMetaDefs.get( name );
+ }
+
+ public FetchProfile findOrCreateFetchProfile(String name) {
+ FetchProfile profile = super.findOrCreateFetchProfile( name );
+ if ( profile.getFetches().isEmpty() ) {
+ annotationConfiguredProfile.add( profile );
+ }
+ return profile;
+ }
+
+ public boolean isAnnotationConfiguredFetchProfile(FetchProfile fetchProfile) {
+ for ( FetchProfile profile : annotationConfiguredProfile ) {
+ // we need reference equality there!!
+ if ( profile == fetchProfile ) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ private static class CacheHolder {
+ public CacheHolder(String role, String usage, String region, boolean isClass, boolean
cacheLazy) {
+ this.role = role;
+ this.usage = usage;
+ this.region = region;
+ this.isClass = isClass;
+ this.cacheLazy = cacheLazy;
+ }
+
+ public String role;
+ public String usage;
+ public String region;
+ public boolean isClass;
+ public boolean cacheLazy;
+ }
+
+ private static class ErrorLogger implements ErrorHandler {
+ private List<SAXParseException> errors;
+
+ public ErrorLogger(List<SAXParseException> errors) {
+ this.errors = errors;
+ }
+
+ public void warning(SAXParseException exception) throws SAXException {
+ errors.add( exception );
+ }
+
+ public void error(SAXParseException exception) throws SAXException {
+ errors.add( exception );
+ }
+
+ public void fatalError(SAXParseException exception) throws SAXException {
+ }
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/BinderHelper.java (from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/BinderHelper.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/BinderHelper.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/BinderHelper.java 2010-07-08 23:41:23
UTC (rev 19921)
@@ -0,0 +1,673 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.AssertionFailure;
+import org.hibernate.MappingException;
+import org.hibernate.annotations.AnyMetaDef;
+import org.hibernate.annotations.AnyMetaDefs;
+import org.hibernate.annotations.MetaValue;
+import org.hibernate.annotations.common.reflection.XAnnotatedElement;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XPackage;
+import org.hibernate.cfg.annotations.EntityBinder;
+import org.hibernate.cfg.annotations.Nullability;
+import org.hibernate.cfg.annotations.TableBinder;
+import org.hibernate.id.MultipleHiLoPerTableGenerator;
+import org.hibernate.id.PersistentIdentifierGenerator;
+import org.hibernate.mapping.Any;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.IdGenerator;
+import org.hibernate.mapping.Join;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.SimpleValue;
+import org.hibernate.mapping.SyntheticProperty;
+import org.hibernate.mapping.Table;
+import org.hibernate.mapping.ToOne;
+import org.hibernate.mapping.Value;
+import org.hibernate.mapping.MappedSuperclass;
+import org.hibernate.util.StringHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class BinderHelper {
+
+ public static final String ANNOTATION_STRING_DEFAULT = "";
+ private static Logger log = LoggerFactory.getLogger( BinderHelper.class );
+
+ private BinderHelper() {
+ }
+
+ static {
+ Set<String> primitiveNames = new HashSet<String>();
+ primitiveNames.add( byte.class.getName() );
+ primitiveNames.add( short.class.getName() );
+ primitiveNames.add( int.class.getName() );
+ primitiveNames.add( long.class.getName() );
+ primitiveNames.add( float.class.getName() );
+ primitiveNames.add( double.class.getName() );
+ primitiveNames.add( char.class.getName() );
+ primitiveNames.add( boolean.class.getName() );
+ PRIMITIVE_NAMES = Collections.unmodifiableSet( primitiveNames );
+ }
+
+ public static final Set<String> PRIMITIVE_NAMES;
+
+ /**
+ * create a property copy reusing the same value
+ */
+ public static Property shallowCopy(Property property) {
+ Property clone = new Property();
+ clone.setCascade( property.getCascade() );
+ clone.setInsertable( property.isInsertable() );
+ clone.setLazy( property.isLazy() );
+ clone.setName( property.getName() );
+ clone.setNodeName( property.getNodeName() );
+ clone.setNaturalIdentifier( property.isNaturalIdentifier() );
+ clone.setOptimisticLocked( property.isOptimisticLocked() );
+ clone.setOptional( property.isOptional() );
+ clone.setPersistentClass( property.getPersistentClass() );
+ clone.setPropertyAccessorName( property.getPropertyAccessorName() );
+ clone.setSelectable( property.isSelectable() );
+ clone.setUpdateable( property.isUpdateable() );
+ clone.setValue( property.getValue() );
+ return clone;
+ }
+
+ public static void createSyntheticPropertyReference(
+ Ejb3JoinColumn[] columns,
+ PersistentClass ownerEntity,
+ PersistentClass associatedEntity,
+ Value value,
+ boolean inverse, ExtendedMappings mappings
+ ) {
+ //associated entity only used for more precise exception, yuk!
+ if ( columns[0].isImplicit() || StringHelper.isNotEmpty( columns[0].getMappedBy() ) )
return;
+ int fkEnum = Ejb3JoinColumn.checkReferencedColumnsType( columns, ownerEntity, mappings
);
+ PersistentClass associatedClass = columns[0].getPropertyHolder() != null ?
+ columns[0].getPropertyHolder().getPersistentClass() :
+ null;
+ if ( Ejb3JoinColumn.NON_PK_REFERENCE == fkEnum ) {
+ /**
+ * Create a synthetic property to refer to including an
+ * embedded component value containing all the properties
+ * mapped to the referenced columns
+ * We need to shallow copy those properties to mark them
+ * as non insertable / non updatable
+ */
+ StringBuilder propertyNameBuffer = new StringBuilder( "_" );
+ propertyNameBuffer.append( associatedClass.getEntityName().replace( '.',
'_' ) );
+ propertyNameBuffer.append( "_" ).append( columns[0].getPropertyName() );
+ String syntheticPropertyName = propertyNameBuffer.toString();
+ //find properties associated to a certain column
+ Object columnOwner = findColumnOwner( ownerEntity, columns[0].getReferencedColumn(),
mappings );
+ List<Property> properties = findPropertiesByColumns( columnOwner, columns,
mappings );
+ //create an embeddable component
+ Property synthProp = null;
+ if ( properties != null ) {
+ //todo how about properties.size() == 1, this should be much simpler
+ Component embeddedComp = columnOwner instanceof PersistentClass ?
+ new Component( mappings, (PersistentClass) columnOwner ) :
+ new Component( mappings, (Join) columnOwner );
+ embeddedComp.setEmbedded( true );
+ embeddedComp.setNodeName( syntheticPropertyName );
+ embeddedComp.setComponentClassName( embeddedComp.getOwner().getClassName() );
+ for (Property property : properties) {
+ Property clone = BinderHelper.shallowCopy( property );
+ clone.setInsertable( false );
+ clone.setUpdateable( false );
+ clone.setNaturalIdentifier( false );
+ clone.setGeneration( property.getGeneration() );
+ embeddedComp.addProperty( clone );
+ }
+ synthProp = new SyntheticProperty();
+ synthProp.setName( syntheticPropertyName );
+ synthProp.setNodeName( syntheticPropertyName );
+ synthProp.setPersistentClass( ownerEntity );
+ synthProp.setUpdateable( false );
+ synthProp.setInsertable( false );
+ synthProp.setValue( embeddedComp );
+ synthProp.setPropertyAccessorName( "embedded" );
+ ownerEntity.addProperty( synthProp );
+ //make it unique
+ TableBinder.createUniqueConstraint( embeddedComp );
+ }
+ else {
+ //TODO use a ToOne type doing a second select
+ StringBuilder columnsList = new StringBuilder();
+ columnsList.append( "referencedColumnNames(" );
+ for (Ejb3JoinColumn column : columns) {
+ columnsList.append( column.getReferencedColumn() ).append( ", " );
+ }
+ columnsList.setLength( columnsList.length() - 2 );
+ columnsList.append( ") " );
+
+ if ( associatedEntity != null ) {
+ //overidden destination
+ columnsList.append( "of " )
+ .append( associatedEntity.getEntityName() )
+ .append( "." )
+ .append( columns[0].getPropertyName() )
+ .append( " " );
+ }
+ else {
+ if ( columns[0].getPropertyHolder() != null ) {
+ columnsList.append( "of " )
+ .append( columns[0].getPropertyHolder().getEntityName() )
+ .append( "." )
+ .append( columns[0].getPropertyName() )
+ .append( " " );
+ }
+ }
+ columnsList.append( "referencing " )
+ .append( ownerEntity.getEntityName() )
+ .append( " not mapped to a single property" );
+ throw new AnnotationException( columnsList.toString() );
+ }
+
+ /**
+ * creating the property ref to the new synthetic property
+ */
+ if ( value instanceof ToOne ) {
+ ( (ToOne) value ).setReferencedPropertyName( syntheticPropertyName );
+ mappings.addUniquePropertyReference( ownerEntity.getEntityName(),
syntheticPropertyName );
+ }
+ else if ( value instanceof Collection ) {
+ ( (Collection) value ).setReferencedPropertyName( syntheticPropertyName );
+ //not unique because we could create a mtm wo association table
+ mappings.addPropertyReference( ownerEntity.getEntityName(), syntheticPropertyName );
+ }
+ else {
+ throw new AssertionFailure(
+ "Do a property ref on an unexpected Value type: "
+ + value.getClass().getName()
+ );
+ }
+ mappings.addPropertyReferencedAssociation(
+ ( inverse ? "inverse__" : "" ) +
associatedClass.getEntityName(),
+ columns[0].getPropertyName(),
+ syntheticPropertyName
+ );
+ }
+ }
+
+
+ private static List<Property> findPropertiesByColumns(
+ Object columnOwner, Ejb3JoinColumn[] columns,
+ ExtendedMappings mappings
+ ) {
+ Map<Column, Set<Property>> columnsToProperty = new HashMap<Column,
Set<Property>>();
+ List<Column> orderedColumns = new ArrayList<Column>( columns.length );
+ Table referencedTable = null;
+ if ( columnOwner instanceof PersistentClass ) {
+ referencedTable = ( (PersistentClass) columnOwner ).getTable();
+ }
+ else if ( columnOwner instanceof Join ) {
+ referencedTable = ( (Join) columnOwner ).getTable();
+ }
+ else {
+ throw new AssertionFailure(
+ columnOwner == null ?
+ "columnOwner is null" :
+ "columnOwner neither PersistentClass nor Join: " +
columnOwner.getClass()
+ );
+ }
+ //build the list of column names
+ for (Ejb3JoinColumn column1 : columns) {
+ Column column = new Column(
+ mappings.getPhysicalColumnName( column1.getReferencedColumn(), referencedTable )
+ );
+ orderedColumns.add( column );
+ columnsToProperty.put( column, new HashSet<Property>() );
+ }
+ boolean isPersistentClass = columnOwner instanceof PersistentClass;
+ Iterator it = isPersistentClass ?
+ ( (PersistentClass) columnOwner ).getPropertyIterator() :
+ ( (Join) columnOwner ).getPropertyIterator();
+ while ( it.hasNext() ) {
+ matchColumnsByProperty( (Property) it.next(), columnsToProperty );
+ }
+ if ( isPersistentClass ) {
+ matchColumnsByProperty( ( (PersistentClass) columnOwner ).getIdentifierProperty(),
columnsToProperty );
+ }
+
+ //first naive implementation
+ //only check 1 columns properties
+ //TODO make it smarter by checking correctly ordered multi column properties
+ List<Property> orderedProperties = new ArrayList<Property>();
+ for (Column column : orderedColumns) {
+ boolean found = false;
+ for (Property property : columnsToProperty.get( column ) ) {
+ if ( property.getColumnSpan() == 1 ) {
+ orderedProperties.add( property );
+ found = true;
+ break;
+ }
+ }
+ if ( !found ) return null; //have to find it the hard way
+ }
+ return orderedProperties;
+ }
+
+ private static void matchColumnsByProperty(Property property, Map<Column,
Set<Property>> columnsToProperty) {
+ if ( property == null ) return;
+ if ( "noop".equals( property.getPropertyAccessorName() )
+ || "embedded".equals( property.getPropertyAccessorName() ) ) {
+ return;
+ }
+// FIXME cannot use subproperties becasue the caller needs top level properties
+// if ( property.isComposite() ) {
+// Iterator subProperties = ( (Component) property.getValue() ).getPropertyIterator();
+// while ( subProperties.hasNext() ) {
+// matchColumnsByProperty( (Property) subProperties.next(), columnsToProperty );
+// }
+// }
+ else {
+ Iterator columnIt = property.getColumnIterator();
+ while ( columnIt.hasNext() ) {
+ Object column = columnIt.next(); //can be a Formula so we don't cast
+ //noinspection SuspiciousMethodCalls
+ if ( columnsToProperty.containsKey( column ) ) {
+ columnsToProperty.get( column ).add( property );
+ }
+ }
+ }
+ }
+
+ /**
+ * Retrieve the property by path in a recursive way, including IndetifierProperty in the
loop
+ * If propertyName is null or empty, the IdentifierProperty is returned
+ */
+ public static Property findPropertyByName(PersistentClass associatedClass, String
propertyName) {
+ Property property = null;
+ Property idProperty = associatedClass.getIdentifierProperty();
+ String idName = idProperty != null ? idProperty.getName() : null;
+ try {
+ if ( propertyName == null
+ || propertyName.length() == 0
+ || propertyName.equals( idName ) ) {
+ //default to id
+ property = idProperty;
+ }
+ else {
+ if ( propertyName.indexOf( idName + "." ) == 0 ) {
+ property = idProperty;
+ propertyName = propertyName.substring( idName.length() + 1 );
+ }
+ StringTokenizer st = new StringTokenizer( propertyName, ".", false );
+ while ( st.hasMoreElements() ) {
+ String element = (String) st.nextElement();
+ if ( property == null ) {
+ property = associatedClass.getProperty( element );
+ }
+ else {
+ if ( !property.isComposite() ) return null;
+ property = ( (Component) property.getValue() ).getProperty( element );
+ }
+ }
+ }
+ }
+ catch (MappingException e) {
+ try {
+ //if we do not find it try to check the identifier mapper
+ if ( associatedClass.getIdentifierMapper() == null ) return null;
+ StringTokenizer st = new StringTokenizer( propertyName, ".", false );
+ while ( st.hasMoreElements() ) {
+ String element = (String) st.nextElement();
+ if ( property == null ) {
+ property = associatedClass.getIdentifierMapper().getProperty( element );
+ }
+ else {
+ if ( !property.isComposite() ) return null;
+ property = ( (Component) property.getValue() ).getProperty( element );
+ }
+ }
+ }
+ catch (MappingException ee) {
+ return null;
+ }
+ }
+ return property;
+ }
+
+ /**
+ * Retrieve the property by path in a recursive way
+ */
+ public static Property findPropertyByName(Component component, String propertyName) {
+ Property property = null;
+ try {
+ if ( propertyName == null
+ || propertyName.length() == 0) {
+ // Do not expect to use a primary key for this case
+ return null;
+ }
+ else {
+ StringTokenizer st = new StringTokenizer( propertyName, ".", false );
+ while ( st.hasMoreElements() ) {
+ String element = (String) st.nextElement();
+ if ( property == null ) {
+ property = component.getProperty( element );
+ }
+ else {
+ if ( !property.isComposite() ) return null;
+ property = ( (Component) property.getValue() ).getProperty( element );
+ }
+ }
+ }
+ }
+ catch (MappingException e) {
+ try {
+ //if we do not find it try to check the identifier mapper
+ if ( component.getOwner().getIdentifierMapper() == null ) return null;
+ StringTokenizer st = new StringTokenizer( propertyName, ".", false );
+ while ( st.hasMoreElements() ) {
+ String element = (String) st.nextElement();
+ if ( property == null ) {
+ property = component.getOwner().getIdentifierMapper().getProperty( element );
+ }
+ else {
+ if ( !property.isComposite() ) return null;
+ property = ( (Component) property.getValue() ).getProperty( element );
+ }
+ }
+ }
+ catch (MappingException ee) {
+ return null;
+ }
+ }
+ return property;
+ }
+
+ public static String getRelativePath(PropertyHolder propertyHolder, String propertyName)
{
+ if ( propertyHolder == null ) return propertyName;
+ String path = propertyHolder.getPath();
+ String entityName = propertyHolder.getPersistentClass().getEntityName();
+ if ( path.length() == entityName.length() ) {
+ return propertyName;
+ }
+ else {
+ return StringHelper.qualify( path.substring( entityName.length() + 1 ), propertyName
);
+ }
+ }
+
+ /**
+ * Find the column owner (ie PersistentClass or Join) of columnName.
+ * If columnName is null or empty, persistentClass is returned
+ */
+ public static Object findColumnOwner(
+ PersistentClass persistentClass, String columnName, ExtendedMappings mappings
+ ) {
+ if ( StringHelper.isEmpty( columnName ) ) {
+ return persistentClass; //shortcut for implicit referenced column names
+ }
+ PersistentClass current = persistentClass;
+ Object result;
+ boolean found = false;
+ do {
+ result = current;
+ Table currentTable = current.getTable();
+ try {
+ mappings.getPhysicalColumnName( columnName, currentTable );
+ found = true;
+ }
+ catch (MappingException me) {
+ //swallow it
+ }
+ Iterator joins = current.getJoinIterator();
+ while ( !found && joins.hasNext() ) {
+ result = joins.next();
+ currentTable = ( (Join) result ).getTable();
+ try {
+ mappings.getPhysicalColumnName( columnName, currentTable );
+ found = true;
+ }
+ catch (MappingException me) {
+ //swallow it
+ }
+ }
+ current = current.getSuperclass();
+ }
+ while ( !found && current != null );
+ return found ? result : null;
+ }
+
+ /**
+ * apply an id generator to a SimpleValue
+ */
+ public static void makeIdGenerator(
+ SimpleValue id, String generatorType, String generatorName, ExtendedMappings
mappings,
+ Map<String, IdGenerator> localGenerators
+ ) {
+ Table table = id.getTable();
+ table.setIdentifierValue( id );
+ //generator settings
+ id.setIdentifierGeneratorStrategy( generatorType );
+ Properties params = new Properties();
+ //always settable
+ params.setProperty(
+ PersistentIdentifierGenerator.TABLE, table.getName()
+ );
+
+ if ( id.getColumnSpan() == 1 ) {
+ params.setProperty(
+ PersistentIdentifierGenerator.PK,
+ ( (org.hibernate.mapping.Column) id.getColumnIterator().next() ).getName()
+ );
+ }
+ // YUCK! but cannot think of a clean way to do this given the string-config based
scheme
+ params.put( PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER,
mappings.getObjectNameNormalizer() );
+
+ if ( !isDefault( generatorName ) ) {
+ //we have a named generator
+ IdGenerator gen = mappings.getGenerator( generatorName, localGenerators );
+ if ( gen == null ) {
+ throw new AnnotationException( "Unknown Id.generator: " + generatorName );
+ }
+ //This is quite vague in the spec but a generator could override the generate choice
+ String identifierGeneratorStrategy = gen.getIdentifierGeneratorStrategy();
+ //yuk! this is a hack not to override 'AUTO' even if generator is set
+ final boolean avoidOverriding =
+ identifierGeneratorStrategy.equals( "identity" )
+ || identifierGeneratorStrategy.equals( "seqhilo" )
+ || identifierGeneratorStrategy.equals(
MultipleHiLoPerTableGenerator.class.getName() );
+ if ( generatorType == null || !avoidOverriding ) {
+ id.setIdentifierGeneratorStrategy( identifierGeneratorStrategy );
+ }
+ //checkIfMatchingGenerator(gen, generatorType, generatorName);
+ Iterator genParams = gen.getParams().entrySet().iterator();
+ while ( genParams.hasNext() ) {
+ Map.Entry elt = (Map.Entry) genParams.next();
+ params.setProperty( (String) elt.getKey(), (String) elt.getValue() );
+ }
+ }
+ if ( "assigned".equals( generatorType ) ) id.setNullValue(
"undefined" );
+ id.setIdentifierGeneratorProperties( params );
+ }
+
+ public static boolean isDefault(String annotationString) {
+ return annotationString != null && annotationString.length() == 0;
+ //equivalent to (but faster) ANNOTATION_STRING_DEFAULT.equals( annotationString );
+ }
+
+ public static Any buildAnyValue(String anyMetaDefName, Ejb3JoinColumn[] columns,
javax.persistence.Column metaColumn, PropertyData inferredData,
+ boolean cascadeOnDelete, Nullability nullability, PropertyHolder
propertyHolder,
+ EntityBinder entityBinder, boolean optional, ExtendedMappings mappings) {
+ //All FK columns should be in the same table
+ Any value = new Any( mappings, columns[0].getTable() );
+ AnyMetaDef metaAnnDef = inferredData.getProperty().getAnnotation( AnyMetaDef.class );
+
+ if ( metaAnnDef != null ) {
+ //local has precedence over general and can be mapped for future reference if named
+ bindAnyMetaDefs( inferredData.getProperty(), mappings );
+ }
+ else {
+ metaAnnDef = mappings.getAnyMetaDef( anyMetaDefName );
+ }
+ if ( metaAnnDef != null ) {
+ value.setIdentifierType( metaAnnDef.idType() );
+ value.setMetaType( metaAnnDef.metaType() );
+
+ HashMap values = new HashMap();
+ org.hibernate.type.Type metaType = mappings.getTypeResolver().heuristicType(
value.getMetaType() );
+ for (MetaValue metaValue : metaAnnDef.metaValues()) {
+ try {
+ Object discrim = ( (org.hibernate.type.DiscriminatorType) metaType ).stringToObject(
metaValue
+ .value() );
+ String entityName = metaValue.targetEntity().getName();
+ values.put( discrim, entityName );
+ }
+ catch (ClassCastException cce) {
+ throw new MappingException( "metaType was not a DiscriminatorType: "
+ + metaType.getName() );
+ }
+ catch (Exception e) {
+ throw new MappingException( "could not interpret metaValue", e );
+ }
+ }
+ if ( !values.isEmpty() ) value.setMetaValues( values );
+ }
+ else {
+ throw new AnnotationException( "Unable to find @AnyMetaDef for an @(ManyTo)Any
mapping: "
+ + StringHelper.qualify( propertyHolder.getPath(), inferredData.getPropertyName() )
);
+ }
+
+ value.setCascadeDeleteEnabled( cascadeOnDelete );
+ if ( !optional ) {
+ for (Ejb3JoinColumn column : columns) {
+ column.setNullable( false );
+ }
+ }
+
+ Ejb3Column[] metaColumns = Ejb3Column.buildColumnFromAnnotation( new
javax.persistence.Column[] { metaColumn }, null,
+ nullability, propertyHolder, inferredData, entityBinder.getSecondaryTables(),
mappings );
+ //set metaColumn to the right table
+ for (Ejb3Column column : metaColumns) {
+ column.setTable( value.getTable() );
+ }
+ //meta column
+ for (Ejb3Column column : metaColumns) {
+ column.linkWithValue( value );
+ }
+
+ //id columns
+ final String propertyName = inferredData.getPropertyName();
+ Ejb3Column.checkPropertyConsistency( columns, propertyHolder.getEntityName() +
propertyName );
+ for (Ejb3JoinColumn column : columns) {
+ column.linkWithValue( value );
+ }
+ return value;
+ }
+
+ public static void bindAnyMetaDefs(XAnnotatedElement annotatedElement, ExtendedMappings
mappings) {
+ AnyMetaDef defAnn = annotatedElement.getAnnotation( AnyMetaDef.class );
+ AnyMetaDefs defsAnn = annotatedElement.getAnnotation( AnyMetaDefs.class );
+ boolean mustHaveName = XClass.class.isAssignableFrom( annotatedElement.getClass() )
+ || XPackage.class.isAssignableFrom( annotatedElement.getClass() );
+ if ( defAnn != null ) {
+ checkAnyMetaDefValidity( mustHaveName, defAnn, annotatedElement );
+ bindAnyMetaDef( defAnn, mappings );
+ }
+ if ( defsAnn != null ) {
+ for (AnyMetaDef def : defsAnn.value()) {
+ checkAnyMetaDefValidity( mustHaveName, def, annotatedElement );
+ bindAnyMetaDef( def, mappings );
+ }
+ }
+ }
+
+ private static void checkAnyMetaDefValidity(boolean mustHaveName, AnyMetaDef defAnn,
XAnnotatedElement annotatedElement) {
+ if ( mustHaveName && isDefault( defAnn.name() ) ) {
+ String name = XClass.class.isAssignableFrom( annotatedElement.getClass() ) ?
+ ( (XClass) annotatedElement ).getName() :
+ ( (XPackage) annotatedElement ).getName();
+ throw new AnnotationException( "(a)AnyMetaDef.name cannot be null on an entity or a
package: " + name );
+ }
+ }
+
+ private static void bindAnyMetaDef(AnyMetaDef defAnn, ExtendedMappings mappings) {
+ if ( isDefault( defAnn.name() ) ) return; //don't map not named definitions
+ log.info( "Binding Any Meta definition: {}", defAnn.name() );
+ mappings.addAnyMetaDef( defAnn );
+ }
+
+ public static MappedSuperclass getMappedSuperclassOrNull(XClass declaringClass,
+ Map<XClass, InheritanceState> inheritanceStatePerClass,
+ ExtendedMappings mappings) {
+ boolean retrieve = false;
+ if ( declaringClass != null ) {
+ final InheritanceState inheritanceState = inheritanceStatePerClass.get( declaringClass
);
+ if ( inheritanceState == null ) {
+ throw new org.hibernate.annotations.common.AssertionFailure(
+ "Declaring class is not found in the inheritance state hierarchy: " +
declaringClass
+ );
+ }
+ if ( inheritanceState.isEmbeddableSuperclass() ) {
+ retrieve = true;
+ }
+ }
+ return retrieve ?
+ mappings.getMappedSuperclass( mappings.getReflectionManager().toClass( declaringClass
) ) :
+ null;
+ }
+
+ public static String getPath(PropertyHolder holder, PropertyData property) {
+ return StringHelper.qualify( holder.getPath(), property.getPropertyName() );
+ }
+
+ static PropertyData getPropertyOverriddenByMapperOrMapsId(boolean isId, PropertyHolder
propertyHolder, String propertyName, ExtendedMappings mappings) {
+ final XClass persistentXClass;
+ try {
+ persistentXClass = mappings.getReflectionManager()
+ .classForName( propertyHolder.getPersistentClass().getClassName(),
AnnotationBinder.class );
+ }
+ catch ( ClassNotFoundException e ) {
+ throw new AssertionFailure( "PersistentClass name cannot be converted into a
Class", e);
+ }
+ if ( propertyHolder.isInIdClass() ) {
+ return mappings.getPropertyAnnotatedWithIdAndToOne( persistentXClass, propertyName );
+ }
+ else {
+ String propertyPath = isId ? "" : propertyName;
+ return mappings.getPropertyAnnotatedWithMapsId( persistentXClass, propertyPath );
+ }
+ }
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/cfg/BinderHelper.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/ClassPropertyHolder.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/cfg/ClassPropertyHolder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/ClassPropertyHolder.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/ClassPropertyHolder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,202 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.JoinTable;
+
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.AssertionFailure;
+import org.hibernate.cfg.annotations.EntityBinder;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.Join;
+import org.hibernate.mapping.KeyValue;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.Table;
+import org.hibernate.mapping.MappedSuperclass;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class ClassPropertyHolder extends AbstractPropertyHolder {
+ private PersistentClass persistentClass;
+ private Map<String, Join> joins;
+ private transient Map<String, Join> joinsPerRealTableName;
+ private EntityBinder entityBinder;
+ private final Map<XClass, InheritanceState> inheritanceStatePerClass;
+
+ public ClassPropertyHolder(
+ PersistentClass persistentClass, XClass clazzToProcess,
+ Map<String, Join> joins, ExtendedMappings mappings, Map<XClass,
InheritanceState> inheritanceStatePerClass
+ ) {
+ super( persistentClass.getEntityName(), null, clazzToProcess, mappings );
+ this.persistentClass = persistentClass;
+ this.joins = joins;
+ this.inheritanceStatePerClass = inheritanceStatePerClass;
+ }
+
+ public ClassPropertyHolder(
+ PersistentClass persistentClass, XClass clazzToProcess, EntityBinder entityBinder,
+ ExtendedMappings mappings, Map<XClass, InheritanceState>
inheritanceStatePerClass
+ ) {
+ this( persistentClass, clazzToProcess, entityBinder.getSecondaryTables(), mappings,
inheritanceStatePerClass );
+ this.entityBinder = entityBinder;
+ }
+
+ public String getEntityName() {
+ return persistentClass.getEntityName();
+ }
+
+ public void addProperty(Property prop, Ejb3Column[] columns, XClass declaringClass) {
+ //Ejb3Column.checkPropertyConsistency( ); //already called earlier
+ if ( columns != null && columns[0].isSecondary() ) {
+ //TODO move the getJoin() code here?
+ final Join join = columns[0].getJoin();
+ addPropertyToJoin( prop, declaringClass, join );
+ }
+ else {
+ addProperty( prop, declaringClass );
+ }
+ }
+
+ public void addProperty(Property prop, XClass declaringClass) {
+ if ( prop.getValue() instanceof Component ) {
+ //TODO handle quote and non quote table comparison
+ String tableName = prop.getValue().getTable().getName();
+ if ( getJoinsPerRealTableName().containsKey( tableName ) ) {
+ final Join join = getJoinsPerRealTableName().get( tableName );
+ addPropertyToJoin( prop, declaringClass, join );
+ }
+ else {
+ addPropertyToPersistentClass( prop, declaringClass );
+ }
+ }
+ else {
+ addPropertyToPersistentClass( prop, declaringClass );
+ }
+ }
+
+ public Join addJoin(JoinTable joinTableAnn, boolean noDelayInPkColumnCreation) {
+ Join join = entityBinder.addJoin( joinTableAnn, this, noDelayInPkColumnCreation );
+ this.joins = entityBinder.getSecondaryTables();
+ return join;
+ }
+
+ private void addPropertyToPersistentClass(Property prop, XClass declaringClass) {
+ if ( declaringClass != null ) {
+ final InheritanceState inheritanceState = inheritanceStatePerClass.get( declaringClass
);
+ if ( inheritanceState == null ) {
+ throw new AssertionFailure(
+ "Declaring class is not found in the inheritance state hierarchy: " +
declaringClass
+ );
+ }
+ if ( inheritanceState.isEmbeddableSuperclass() ) {
+ persistentClass.addMappedsuperclassProperty(prop);
+ addPropertyToMappedSuperclass( prop, declaringClass );
+ }
+ else {
+ persistentClass.addProperty( prop );
+ }
+ }
+ else {
+ persistentClass.addProperty( prop );
+ }
+ }
+
+ private void addPropertyToMappedSuperclass(Property prop, XClass declaringClass) {
+ final ExtendedMappings mappings = getMappings();
+ final Class type = mappings.getReflectionManager().toClass( declaringClass );
+ MappedSuperclass superclass = mappings.getMappedSuperclass( type );
+ superclass.addDeclaredProperty( prop );
+ }
+
+ private void addPropertyToJoin(Property prop, XClass declaringClass, Join join) {
+ if ( declaringClass != null ) {
+ final InheritanceState inheritanceState = inheritanceStatePerClass.get( declaringClass
);
+ if ( inheritanceState == null ) {
+ throw new AssertionFailure(
+ "Declaring class is not found in the inheritance state hierarchy: " +
declaringClass
+ );
+ }
+ if ( inheritanceState.isEmbeddableSuperclass() ) {
+ join.addMappedsuperclassProperty(prop);
+ addPropertyToMappedSuperclass( prop, declaringClass );
+ }
+ else {
+ join.addProperty( prop );
+ }
+ }
+ else {
+ join.addProperty( prop );
+ }
+ }
+
+ /**
+ * Needed for proper compliance with naming strategy, the property table
+ * can be overriden if the properties are part of secondary tables
+ */
+ private Map<String, Join> getJoinsPerRealTableName() {
+ if ( joinsPerRealTableName == null ) {
+ joinsPerRealTableName = new HashMap<String, Join>( joins.size() );
+ for (Join join : joins.values()) {
+ joinsPerRealTableName.put( join.getTable().getName(), join );
+ }
+ }
+ return joinsPerRealTableName;
+ }
+
+ public String getClassName() {
+ return persistentClass.getClassName();
+ }
+
+ public String getEntityOwnerClassName() {
+ return getClassName();
+ }
+
+ public Table getTable() {
+ return persistentClass.getTable();
+ }
+
+ public boolean isComponent() {
+ return false;
+ }
+
+ public boolean isEntity() {
+ return true;
+ }
+
+ public PersistentClass getPersistentClass() {
+ return persistentClass;
+ }
+
+ public KeyValue getIdentifier() {
+ return persistentClass.getIdentifier();
+ }
+
+ public boolean isOrWithinEmbeddedId() {
+ return false;
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/ClassPropertyHolder.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/CollectionPropertyHolder.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/CollectionPropertyHolder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/CollectionPropertyHolder.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/CollectionPropertyHolder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,101 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import javax.persistence.JoinTable;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.Join;
+import org.hibernate.mapping.KeyValue;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.Table;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class CollectionPropertyHolder extends AbstractPropertyHolder {
+ Collection collection;
+
+ public CollectionPropertyHolder(
+ Collection collection, String path, XClass clazzToProcess, XProperty property,
+ PropertyHolder parentPropertyHolder, ExtendedMappings mappings
+ ) {
+ super( path, parentPropertyHolder, clazzToProcess, mappings );
+ this.collection = collection;
+ setCurrentProperty( property );
+ }
+
+ public String getClassName() {
+ throw new AssertionFailure( "Collection property holder does not have a class
name" );
+ }
+
+ public String getEntityOwnerClassName() {
+ return null;
+ }
+
+ public Table getTable() {
+ return collection.getCollectionTable();
+ }
+
+ public void addProperty(Property prop, XClass declaringClass) {
+ throw new AssertionFailure( "Cannot add property to a collection" );
+ }
+
+ public KeyValue getIdentifier() {
+ throw new AssertionFailure( "Identifier collection not yet managed" );
+ }
+
+ public boolean isOrWithinEmbeddedId() {
+ return false;
+ }
+
+ public PersistentClass getPersistentClass() {
+ return collection.getOwner();
+ }
+
+ public boolean isComponent() {
+ return false;
+ }
+
+ public boolean isEntity() {
+ return false;
+ }
+
+ public String getEntityName() {
+ return collection.getOwner().getEntityName();
+ }
+
+ public void addProperty(Property prop, Ejb3Column[] columns, XClass declaringClass) {
+ //Ejb3Column.checkPropertyConsistency( ); //already called earlier
+ throw new AssertionFailure( "addProperty to a join table of a collection: does it
make sense?" );
+ }
+
+ public Join addJoin(JoinTable joinTableAnn, boolean noDelayInPkColumnCreation) {
+ throw new AssertionFailure( "Add a <join> in a second pass" );
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/CollectionPropertyHolder.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/ColumnsBuilder.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/cfg/ColumnsBuilder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/ColumnsBuilder.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/ColumnsBuilder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,212 @@
+package org.hibernate.cfg;
+
+import javax.persistence.Column;
+import javax.persistence.ElementCollection;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinColumns;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.annotations.CollectionOfElements;
+import org.hibernate.annotations.Columns;
+import org.hibernate.annotations.Formula;
+import org.hibernate.annotations.JoinColumnsOrFormulas;
+import org.hibernate.annotations.JoinFormula;
+import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.cfg.annotations.EntityBinder;
+import org.hibernate.cfg.annotations.Nullability;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Do the initial discovery of columns metadata and apply defaults.
+ * Also hosts some convinient methods related to column processing
+ *
+ * @author Emmanuel Bernard
+ */
+class ColumnsBuilder {
+ private PropertyHolder propertyHolder;
+ private Nullability nullability;
+ private XProperty property;
+ private PropertyData inferredData;
+ private EntityBinder entityBinder;
+ private ExtendedMappings mappings;
+ private Ejb3Column[] columns;
+ private Ejb3JoinColumn[] joinColumns;
+
+ public ColumnsBuilder(PropertyHolder propertyHolder, Nullability nullability, XProperty
property, PropertyData inferredData, EntityBinder entityBinder, ExtendedMappings mappings)
{
+ this.propertyHolder = propertyHolder;
+ this.nullability = nullability;
+ this.property = property;
+ this.inferredData = inferredData;
+ this.entityBinder = entityBinder;
+ this.mappings = mappings;
+ }
+
+ public Ejb3Column[] getColumns() {
+ return columns;
+ }
+
+ public Ejb3JoinColumn[] getJoinColumns() {
+ return joinColumns;
+ }
+
+ public ColumnsBuilder extractMetadata() {
+ columns = null;
+ joinColumns = buildExplicitJoinColumns(property, inferredData);
+
+
+ if ( property.isAnnotationPresent( Column.class ) || property.isAnnotationPresent(
Formula.class ) ) {
+ Column ann = property.getAnnotation( Column.class );
+ Formula formulaAnn = property.getAnnotation( Formula.class );
+ columns = Ejb3Column.buildColumnFromAnnotation(
+ new Column[] { ann }, formulaAnn, nullability, propertyHolder, inferredData,
+ entityBinder.getSecondaryTables(), mappings
+ );
+ }
+ else if ( property.isAnnotationPresent( Columns.class ) ) {
+ Columns anns = property.getAnnotation( Columns.class );
+ columns = Ejb3Column.buildColumnFromAnnotation(
+ anns.columns(), null,
+ nullability, propertyHolder, inferredData, entityBinder.getSecondaryTables(),
+ mappings
+ );
+ }
+
+ //set default values if needed
+ if ( joinColumns == null &&
+ ( property.isAnnotationPresent( ManyToOne.class )
+ || property.isAnnotationPresent( OneToOne.class ) )
+ ) {
+ joinColumns = buildDefaultJoinColumnsForXToOne(property, inferredData);
+ }
+ else if ( joinColumns == null &&
+ ( property.isAnnotationPresent( OneToMany.class )
+ || property.isAnnotationPresent( CollectionOfElements.class ) //legacy Hibernate
+ || property.isAnnotationPresent( ElementCollection.class )
+ ) ) {
+ OneToMany oneToMany = property.getAnnotation( OneToMany.class );
+ String mappedBy = oneToMany != null ?
+ oneToMany.mappedBy() :
+ "";
+ joinColumns = Ejb3JoinColumn.buildJoinColumns(
+ null,
+ mappedBy, entityBinder.getSecondaryTables(),
+ propertyHolder, inferredData.getPropertyName(), mappings
+ );
+ }
+ else if ( joinColumns == null && property.isAnnotationPresent(
org.hibernate.annotations.Any.class ) ) {
+ throw new AnnotationException( "@Any requires an explicit @JoinColumn(s): "
+ + BinderHelper.getPath( propertyHolder, inferredData ) );
+ }
+ if ( columns == null && !property.isAnnotationPresent( ManyToMany.class ) ) {
+ //useful for collection of embedded elements
+ columns = Ejb3Column.buildColumnFromAnnotation(
+ null, null,
+ nullability, propertyHolder, inferredData, entityBinder.getSecondaryTables(),
mappings
+ );
+ }
+
+ if ( nullability == Nullability.FORCED_NOT_NULL ) {
+ //force columns to not null
+ for (Ejb3Column col : columns ) {
+ col.forceNotNull();
+ }
+ }
+ return this;
+ }
+
+ Ejb3JoinColumn[] buildDefaultJoinColumnsForXToOne(XProperty property, PropertyData
inferredData) {
+ Ejb3JoinColumn[] joinColumns;
+ JoinTable joinTableAnn = propertyHolder.getJoinTable( property );
+ if ( joinTableAnn != null ) {
+ joinColumns = Ejb3JoinColumn.buildJoinColumns(
+ joinTableAnn.inverseJoinColumns(), null, entityBinder.getSecondaryTables(),
+ propertyHolder, inferredData.getPropertyName(), mappings
+ );
+ if ( StringHelper.isEmpty( joinTableAnn.name() ) ) {
+ throw new AnnotationException(
+ "JoinTable.name() on a @ToOne association has to be explicit: "
+ + BinderHelper.getPath( propertyHolder, inferredData )
+ );
+ }
+ }
+ else {
+ OneToOne oneToOneAnn = property.getAnnotation( OneToOne.class );
+ String mappedBy = oneToOneAnn != null ?
+ oneToOneAnn.mappedBy() :
+ null;
+ joinColumns = Ejb3JoinColumn.buildJoinColumns(
+ null,
+ mappedBy, entityBinder.getSecondaryTables(),
+ propertyHolder, inferredData.getPropertyName(), mappings
+ );
+ }
+ return joinColumns;
+ }
+
+ Ejb3JoinColumn[] buildExplicitJoinColumns(XProperty property, PropertyData inferredData)
{
+ //process @JoinColumn(s) before @Column(s) to handle collection of entities properly
+ Ejb3JoinColumn[] joinColumns = null;
+ {
+ JoinColumn[] anns = null;
+
+ if ( property.isAnnotationPresent( JoinColumn.class ) ) {
+ anns = new JoinColumn[] { property.getAnnotation( JoinColumn.class ) };
+ }
+ else if ( property.isAnnotationPresent( JoinColumns.class ) ) {
+ JoinColumns ann = property.getAnnotation( JoinColumns.class );
+ anns = ann.value();
+ int length = anns.length;
+ if ( length == 0 ) {
+ throw new AnnotationException( "Cannot bind an empty @JoinColumns" );
+ }
+ }
+ if ( anns != null ) {
+ joinColumns = Ejb3JoinColumn.buildJoinColumns(
+ anns, null, entityBinder.getSecondaryTables(),
+ propertyHolder, inferredData.getPropertyName(), mappings
+ );
+ }
+ else if ( property.isAnnotationPresent( JoinColumnsOrFormulas.class ) ) {
+ JoinColumnsOrFormulas ann = property.getAnnotation( JoinColumnsOrFormulas.class );
+ joinColumns = Ejb3JoinColumn.buildJoinColumnsOrFormulas(
+ ann, null, entityBinder.getSecondaryTables(),
+ propertyHolder, inferredData.getPropertyName(), mappings
+ );
+ }
+ else if (property.isAnnotationPresent( JoinFormula.class)) {
+ JoinFormula ann = property.getAnnotation( JoinFormula.class );
+ joinColumns = new Ejb3JoinColumn[1];
+ joinColumns[0] = Ejb3JoinColumn.buildJoinFormula(
+ ann, null, entityBinder.getSecondaryTables(),
+ propertyHolder, inferredData.getPropertyName(), mappings);
+ }
+ }
+ return joinColumns;
+ }
+
+ Ejb3Column[] overrideColumnFromMapperOrMapsIdProperty(boolean isId) {
+ Ejb3Column[] result = columns;
+ final PropertyData overridingProperty =
BinderHelper.getPropertyOverriddenByMapperOrMapsId( isId, propertyHolder,
property.getName(), mappings );
+ if ( overridingProperty != null ) {
+ result = buildExcplicitOrDefaultJoinColumn( overridingProperty );
+ }
+ return result;
+ }
+
+ /**
+ * useful to override a column either by @MapsId or by @IdClass
+ */
+ Ejb3Column[] buildExcplicitOrDefaultJoinColumn(PropertyData overridingProperty) {
+ Ejb3Column[] result;
+ result = buildExplicitJoinColumns( overridingProperty.getProperty(), overridingProperty
);
+ if (result == null) {
+ result = buildDefaultJoinColumnsForXToOne( overridingProperty.getProperty(),
overridingProperty);
+ }
+ return result;
+ }
+}
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/ComponentPropertyHolder.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/ComponentPropertyHolder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/ComponentPropertyHolder.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/ComponentPropertyHolder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,175 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import javax.persistence.Column;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.Join;
+import org.hibernate.mapping.KeyValue;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.Table;
+
+/**
+ * Component implementation of property holder
+ *
+ * @author Emmanuel Bernard
+ */
+public class ComponentPropertyHolder extends AbstractPropertyHolder {
+ //TODO introduce a overrideTable() method for columns held by sec table rather than the
hack
+ // joinsPerRealTableName in ClassPropertyHolder
+ private Component component;
+ private boolean isOrWithinEmbeddedId;
+
+ public String getEntityName() {
+ return component.getComponentClassName();
+ }
+
+ public void addProperty(Property prop, Ejb3Column[] columns, XClass declaringClass) {
+ //Ejb3Column.checkPropertyConsistency( ); //already called earlier
+ /*
+ * Check table matches between the component and the columns
+ * if not, change the component table if no properties are set
+ * if a property is set already the core cannot support that
+ */
+ if (columns != null) {
+ Table table = columns[0].getTable();
+ if ( !table.equals( component.getTable() ) ) {
+ if ( component.getPropertySpan() == 0 ) {
+ component.setTable( table );
+ }
+ else {
+ throw new AnnotationException(
+ "A component cannot hold properties split into 2 different tables: "
+ + this.getPath()
+ );
+ }
+ }
+ }
+ addProperty( prop, declaringClass );
+ }
+
+ public Join addJoin(JoinTable joinTableAnn, boolean noDelayInPkColumnCreation) {
+ return parent.addJoin( joinTableAnn, noDelayInPkColumnCreation );
+
+ }
+
+ public ComponentPropertyHolder(
+ Component component, String path, PropertyData inferredData, PropertyHolder parent,
+ ExtendedMappings mappings
+ ) {
+ super( path, parent, inferredData.getPropertyClass(), mappings );
+ final XProperty property = inferredData.getProperty();
+ setCurrentProperty( property );
+ this.component = component;
+ this.isOrWithinEmbeddedId =
+ parent.isOrWithinEmbeddedId()
+ || ( property != null &&
+ ( property.isAnnotationPresent( Id.class )
+ || property.isAnnotationPresent( EmbeddedId.class ) ) );
+ }
+
+ public String getClassName() {
+ return component.getComponentClassName();
+ }
+
+ public String getEntityOwnerClassName() {
+ return component.getOwner().getClassName();
+ }
+
+ public Table getTable() {
+ return component.getTable();
+ }
+
+ public void addProperty(Property prop, XClass declaringClass) {
+ component.addProperty( prop );
+ }
+
+ public KeyValue getIdentifier() {
+ return component.getOwner().getIdentifier();
+ }
+
+ public boolean isOrWithinEmbeddedId() {
+ return isOrWithinEmbeddedId;
+ }
+
+ public PersistentClass getPersistentClass() {
+ return component.getOwner();
+ }
+
+ public boolean isComponent() {
+ return true;
+ }
+
+ public boolean isEntity() {
+ return false;
+ }
+
+ public void setParentProperty(String parentProperty) {
+ component.setParentProperty( parentProperty );
+ }
+
+ @Override
+ public Column[] getOverriddenColumn(String propertyName) {
+ //FIXME this is yukky
+ Column[] result = super.getOverriddenColumn( propertyName );
+ if ( result == null ) {
+ String userPropertyName = extractUserPropertyName( "id", propertyName );
+ if ( userPropertyName != null ) result = super.getOverriddenColumn( userPropertyName
);
+ }
+ if ( result == null ) {
+ String userPropertyName = extractUserPropertyName( "_identifierMapper",
propertyName );
+ if ( userPropertyName != null ) result = super.getOverriddenColumn( userPropertyName
);
+ }
+ return result;
+ }
+
+ private String extractUserPropertyName(String redundantString, String propertyName) {
+ String result = null;
+ String className = component.getOwner().getClassName();
+ if ( propertyName.startsWith( className )
+ && propertyName.length() > className.length() + 2 +
redundantString.length() // .id.
+ && propertyName.substring(
+ className.length() + 1, className.length() + 1 + redundantString.length()
+ ).equals( redundantString )
+ ) {
+ //remove id we might be in a @IdCLass case
+ result = className + propertyName.substring( className.length() + 1 +
redundantString.length() );
+ }
+ return result;
+ }
+
+ @Override
+ public JoinColumn[] getOverriddenJoinColumn(String propertyName) {
+ return super.getOverriddenJoinColumn( propertyName );
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/ComponentPropertyHolder.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/ConfigurationArtefactType.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/ConfigurationArtefactType.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/ConfigurationArtefactType.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/ConfigurationArtefactType.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,49 @@
+// $Id$
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import org.hibernate.HibernateException;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public enum ConfigurationArtefactType {
+ HBM,
+ CLASS;
+
+ static ConfigurationArtefactType parsePrecedence(String s) {
+ if ( s.equalsIgnoreCase( "hbm" ) ) {
+ return HBM;
+ }
+ else if ( s.equalsIgnoreCase( "class" ) ) {
+ return CLASS;
+ }
+ else {
+ throw new HibernateException( "'" + s + "' - invalid value for
precedence configuration." );
+ }
+ }
+}
+
+
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/ConfigurationArtefactType.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied:
core/trunk/core/src/main/java/org/hibernate/cfg/CopyIdentifierComponentSecondPass.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/CopyIdentifierComponentSecondPass.java)
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/cfg/CopyIdentifierComponentSecondPass.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/CopyIdentifierComponentSecondPass.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,131 @@
+package org.hibernate.cfg;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.AssertionFailure;
+import org.hibernate.MappingException;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.SimpleValue;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class CopyIdentifierComponentSecondPass implements SecondPass {
+ private final String referencedEntityName;
+ private final Component component;
+ private final ExtendedMappings mappings;
+ private final Ejb3JoinColumn[] joinColumns;
+
+ public CopyIdentifierComponentSecondPass(
+ Component comp, String referencedEntityName, Ejb3JoinColumn[] joinColumns,
ExtendedMappings mappings) {
+ this.component = comp;
+ this.referencedEntityName = referencedEntityName;
+ this.mappings = mappings;
+ this.joinColumns = joinColumns;
+ }
+
+ //FIXME better error names
+ public void doSecondPass(Map persistentClasses) throws MappingException {
+ PersistentClass referencedPersistentClass = (PersistentClass) persistentClasses.get(
referencedEntityName );
+ if ( referencedPersistentClass == null ) {
+ throw new AnnotationException(
+ "Unknown entity name: " + referencedEntityName
+ );
+ };
+ if ( ! ( referencedPersistentClass.getIdentifier() instanceof Component ) ) {
+ throw new AssertionFailure( "Unexpected identifier type on the referenced entity
when mapping a @MapsId: "
+ + referencedEntityName);
+ }
+ Component referencedComponent = (Component) referencedPersistentClass.getIdentifier();
+ Iterator<Property> properties = referencedComponent.getPropertyIterator();
+
+
+ //prepare column name structure
+ boolean isExplicitReference = true;
+ Map<String, Ejb3JoinColumn> columnByReferencedName = new HashMap<String,
Ejb3JoinColumn>(joinColumns.length);
+ for (Ejb3JoinColumn joinColumn : joinColumns) {
+ final String referencedColumnName = joinColumn.getReferencedColumn();
+ if ( referencedColumnName == null || BinderHelper.isDefault( referencedColumnName ) )
{
+ break;
+ }
+ //JPA 2 requires referencedColumnNames to be case insensitive
+ columnByReferencedName.put( referencedColumnName.toLowerCase(), joinColumn );
+ }
+ //try default column orientation
+ int index = 0;
+ if ( columnByReferencedName.isEmpty() ) {
+ isExplicitReference = false;
+ for (Ejb3JoinColumn joinColumn : joinColumns) {
+ columnByReferencedName.put( "" + index, joinColumn );
+ index++;
+ }
+ index = 0;
+ }
+
+ while ( properties.hasNext() ) {
+ Property referencedProperty = properties.next();
+ if ( referencedProperty.isComposite() ) {
+ throw new AssertionFailure( "Unexpected nested component on the referenced
entity when mapping a @MapsId: "
+ + referencedEntityName);
+ }
+ else {
+ Property property = new Property();
+ property.setName( referencedProperty.getName() );
+ property.setNodeName( referencedProperty.getNodeName() );
+ //FIXME set optional?
+ //property.setOptional( property.isOptional() );
+ property.setPersistentClass( component.getOwner() );
+ property.setPropertyAccessorName( referencedProperty.getPropertyAccessorName() );
+ SimpleValue value = new SimpleValue( mappings, component.getTable() );
+ property.setValue( value );
+ final SimpleValue referencedValue = (SimpleValue) referencedProperty.getValue();
+ value.setTypeName( referencedValue.getTypeName() );
+ value.setTypeParameters( referencedValue.getTypeParameters() );
+ final Iterator<Column> columns = referencedValue.getColumnIterator();
+
+ if ( joinColumns[0].isNameDeferred() ) {
+ joinColumns[0].copyReferencedStructureAndCreateDefaultJoinColumns(
+ referencedPersistentClass,
+ columns,
+ value);
+ }
+ else {
+ //FIXME take care of Formula
+ while ( columns.hasNext() ) {
+ Column column = columns.next();
+ final Ejb3JoinColumn joinColumn;
+ String logicalColumnName = null;
+ if ( isExplicitReference ) {
+ final String columnName = column.getName();
+ logicalColumnName = mappings.getLogicalColumnName( columnName,
referencedPersistentClass.getTable() );
+ //JPA 2 requires referencedColumnNames to be case insensitive
+ joinColumn = columnByReferencedName.get( logicalColumnName.toLowerCase() );
+ }
+ else {
+ joinColumn = columnByReferencedName.get( "" + index );
+ index++;
+ }
+ if ( joinColumn == null && ! joinColumns[0].isNameDeferred() ) {
+ throw new AnnotationException(
+ isExplicitReference ?
+ "Unable to find column reference in the @MapsId mapping: " +
logicalColumnName :
+ "Implicit column reference in the @MapsId mapping fails, try to use
explicit referenceColumnNames: " + referencedEntityName
+ );
+ }
+ final String columnName = joinColumn == null || joinColumn.isNameDeferred() ?
"tata_" + column.getName() : joinColumn
+ .getName();
+ value.addColumn( new Column( columnName ) );
+ column.setValue( value );
+ }
+ }
+ component.addProperty( property );
+ }
+ }
+ }
+}
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/CreateKeySecondPass.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/cfg/CreateKeySecondPass.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/CreateKeySecondPass.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/CreateKeySecondPass.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,59 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.util.Map;
+
+import org.hibernate.MappingException;
+import org.hibernate.mapping.JoinedSubclass;
+import org.hibernate.mapping.RootClass;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class CreateKeySecondPass implements SecondPass {
+ private RootClass rootClass;
+ private JoinedSubclass joinedSubClass;
+
+ public CreateKeySecondPass(RootClass rootClass) {
+ this.rootClass = rootClass;
+ }
+
+ public CreateKeySecondPass(JoinedSubclass joinedSubClass) {
+ this.joinedSubClass = joinedSubClass;
+ }
+
+ public void doSecondPass(Map persistentClasses) throws MappingException {
+ if ( rootClass != null ) {
+ rootClass.createPrimaryKey();
+ }
+ else if ( joinedSubClass != null ) {
+ joinedSubClass.createPrimaryKey();
+ joinedSubClass.createForeignKey();
+ }
+ else {
+ throw new AssertionError( "rootClass and joinedSubClass are null" );
+ }
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/CreateKeySecondPass.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied:
core/trunk/core/src/main/java/org/hibernate/cfg/DefaultComponentSafeNamingStrategy.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/DefaultComponentSafeNamingStrategy.java)
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/cfg/DefaultComponentSafeNamingStrategy.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/DefaultComponentSafeNamingStrategy.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,99 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.util.StringHelper;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class DefaultComponentSafeNamingStrategy extends EJB3NamingStrategy {
+ public static final NamingStrategy INSTANCE = new DefaultComponentSafeNamingStrategy();
+
+ protected static String addUnderscores(String name) {
+ return name.replace( '.', '_' ).toLowerCase();
+ }
+
+ @Override
+ public String propertyToColumnName(String propertyName) {
+ return addUnderscores( propertyName );
+ }
+
+ @Override
+ public String collectionTableName(
+ String ownerEntity, String ownerEntityTable, String associatedEntity, String
associatedEntityTable,
+ String propertyName
+ ) {
+ return tableName(
+ new StringBuilder( ownerEntityTable ).append( "_" )
+ .append(
+ associatedEntityTable != null ?
+ associatedEntityTable :
+ addUnderscores( propertyName )
+ ).toString()
+ );
+ }
+
+
+ public String foreignKeyColumnName(
+ String propertyName, String propertyEntityName, String propertyTableName, String
referencedColumnName
+ ) {
+ String header = propertyName != null ? addUnderscores( propertyName ) :
propertyTableName;
+ if ( header == null ) throw new AssertionFailure( "NamingStrategy not properly
filled" );
+ return columnName( header + "_" + referencedColumnName );
+ }
+
+ @Override
+ public String logicalColumnName(String columnName, String propertyName) {
+ return StringHelper.isNotEmpty( columnName ) ? columnName : propertyName;
+ }
+
+ @Override
+ public String logicalCollectionTableName(
+ String tableName, String ownerEntityTable, String associatedEntityTable, String
propertyName
+ ) {
+ if ( tableName != null ) {
+ return tableName;
+ }
+ else {
+ //use of a stringbuffer to workaround a JDK bug
+ return new StringBuffer( ownerEntityTable ).append( "_" )
+ .append(
+ associatedEntityTable != null ?
+ associatedEntityTable :
+ propertyName
+ ).toString();
+ }
+
+ }
+
+ @Override
+ public String logicalCollectionColumnName(String columnName, String propertyName, String
referencedColumn) {
+ return StringHelper.isNotEmpty( columnName ) ?
+ columnName :
+ propertyName + "_" + referencedColumn;
+ }
+
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/DefaultComponentSafeNamingStrategy.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/EJB3DTDEntityResolver.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/EJB3DTDEntityResolver.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/EJB3DTDEntityResolver.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/EJB3DTDEntityResolver.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,112 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.io.InputStream;
+
+import org.hibernate.util.DTDEntityResolver;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Resolve JPA xsd files locally
+ *
+ * @author Emmanuel Bernard
+ */
+public class EJB3DTDEntityResolver extends DTDEntityResolver {
+ public static final EntityResolver INSTANCE = new EJB3DTDEntityResolver();
+
+ private final Logger log = LoggerFactory.getLogger( EJB3DTDEntityResolver.class );
+
+ boolean resolved = false;
+
+ /**
+ * Persistence.xml has been resolved locally
+ * @return true if it has
+ */
+ public boolean isResolved() {
+ return resolved;
+ }
+
+ public InputSource resolveEntity(String publicId, String systemId) {
+ log.trace("Resolving XML entity {} : {}", publicId, systemId);
+ InputSource is = super.resolveEntity( publicId, systemId );
+ if ( is == null ) {
+ if ( systemId != null ) {
+ if ( systemId.endsWith( "orm_1_0.xsd" ) ) {
+ InputStream dtdStream = getStreamFromClasspath( "orm_1_0.xsd" );
+ final InputSource source = buildInputSource( publicId, systemId, dtdStream, false
);
+ if (source != null) return source;
+ }
+ else if ( systemId.endsWith( "orm_2_0.xsd" ) ) {
+ InputStream dtdStream = getStreamFromClasspath( "orm_2_0.xsd" );
+ final InputSource source = buildInputSource( publicId, systemId, dtdStream, false
);
+ if (source != null) return source;
+ }
+ else if ( systemId.endsWith( "persistence_1_0.xsd" ) ) {
+ InputStream dtdStream = getStreamFromClasspath( "persistence_1_0.xsd" );
+ final InputSource source = buildInputSource( publicId, systemId, dtdStream, true );
+ if (source != null) return source;
+ }
+ else if ( systemId.endsWith( "persistence_2_0.xsd" ) ) {
+ InputStream dtdStream = getStreamFromClasspath( "persistence_2_0.xsd" );
+ final InputSource source = buildInputSource( publicId, systemId, dtdStream, true );
+ if (source != null) return source;
+ }
+ }
+ }
+ else {
+ resolved = true;
+ return is;
+ }
+ //use the default behavior
+ return null;
+ }
+
+ private InputSource buildInputSource(String publicId, String systemId, InputStream
dtdStream, boolean resolved) {
+ if ( dtdStream == null ) {
+ log.trace( "unable to locate [{}] on classpath", systemId );
+ return null;
+ }
+ else {
+ log.trace( "located [{}] in classpath", systemId );
+ InputSource source = new InputSource( dtdStream );
+ source.setPublicId( publicId );
+ source.setSystemId( systemId );
+ this.resolved = resolved;
+ return source;
+ }
+ }
+
+ private InputStream getStreamFromClasspath(String fileName) {
+ log.trace(
+ "recognized JPA ORM namespace; attempting to resolve on classpath under
org/hibernate/ejb"
+ );
+ String path = "org/hibernate/ejb/" + fileName;
+ InputStream dtdStream = resolveInHibernateNamespace( path );
+ return dtdStream;
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/EJB3DTDEntityResolver.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/EJB3NamingStrategy.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/cfg/EJB3NamingStrategy.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/EJB3NamingStrategy.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/EJB3NamingStrategy.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,108 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.io.Serializable;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Naming strategy implementing the EJB3 standards
+ *
+ * @author Emmanuel Bernard
+ */
+public class EJB3NamingStrategy implements NamingStrategy, Serializable {
+ public static final NamingStrategy INSTANCE = new EJB3NamingStrategy();
+
+ public String classToTableName(String className) {
+ return StringHelper.unqualify( className );
+ }
+
+ public String propertyToColumnName(String propertyName) {
+ return StringHelper.unqualify( propertyName );
+ }
+
+ public String tableName(String tableName) {
+ return tableName;
+ }
+
+ public String columnName(String columnName) {
+ return columnName;
+ }
+
+ public String collectionTableName(
+ String ownerEntity, String ownerEntityTable, String associatedEntity, String
associatedEntityTable,
+ String propertyName
+ ) {
+ return tableName(
+ new StringBuilder( ownerEntityTable ).append( "_" )
+ .append(
+ associatedEntityTable != null ?
+ associatedEntityTable :
+ StringHelper.unqualify( propertyName )
+ ).toString()
+ );
+ }
+
+ public String joinKeyColumnName(String joinedColumn, String joinedTable) {
+ return columnName( joinedColumn );
+ }
+
+ public String foreignKeyColumnName(
+ String propertyName, String propertyEntityName, String propertyTableName, String
referencedColumnName
+ ) {
+ String header = propertyName != null ? StringHelper.unqualify( propertyName ) :
propertyTableName;
+ if ( header == null ) throw new AssertionFailure( "NamingStrategy not properly
filled" );
+ return columnName( header + "_" + referencedColumnName );
+ }
+
+ public String logicalColumnName(String columnName, String propertyName) {
+ return StringHelper.isNotEmpty( columnName ) ? columnName : StringHelper.unqualify(
propertyName );
+ }
+
+ public String logicalCollectionTableName(
+ String tableName,
+ String ownerEntityTable, String associatedEntityTable, String propertyName
+ ) {
+ if ( tableName != null ) {
+ return tableName;
+ }
+ else {
+ //use of a stringbuffer to workaround a JDK bug
+ return new StringBuffer( ownerEntityTable ).append( "_" )
+ .append(
+ associatedEntityTable != null ?
+ associatedEntityTable :
+ StringHelper.unqualify( propertyName )
+ ).toString();
+ }
+ }
+
+ public String logicalCollectionColumnName(String columnName, String propertyName, String
referencedColumn) {
+ return StringHelper.isNotEmpty( columnName ) ?
+ columnName :
+ StringHelper.unqualify( propertyName ) + "_" + referencedColumn;
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/EJB3NamingStrategy.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/Ejb3Column.java (from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/Ejb3Column.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/Ejb3Column.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/Ejb3Column.java 2010-07-08 23:41:23
UTC (rev 19921)
@@ -0,0 +1,575 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.util.Map;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.AssertionFailure;
+import org.hibernate.annotations.Index;
+import org.hibernate.cfg.annotations.Nullability;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.Formula;
+import org.hibernate.mapping.Join;
+import org.hibernate.mapping.SimpleValue;
+import org.hibernate.mapping.Table;
+import org.hibernate.util.StringHelper;
+import org.slf4j.LoggerFactory;
+import org.slf4j.Logger;
+
+/**
+ * Wrap state of an EJB3 @Column annotation
+ * and build the Hibernate column mapping element
+ *
+ * @author Emmanuel Bernard
+ */
+public class Ejb3Column {
+ private static final Logger log = LoggerFactory.getLogger( Ejb3Column.class );
+ private Column mappingColumn;
+ private boolean insertable = true;
+ private boolean updatable = true;
+ private String secondaryTableName;
+ protected Map<String, Join> joins;
+ protected PropertyHolder propertyHolder;
+ private ExtendedMappings mappings;
+ private boolean isImplicit;
+ public static final int DEFAULT_COLUMN_LENGTH = 255;
+ public String sqlType;
+ private int length = DEFAULT_COLUMN_LENGTH;
+ private int precision;
+ private int scale;
+ private String logicalColumnName;
+ private String propertyName;
+ private boolean unique;
+ private boolean nullable = true;
+ private String formulaString;
+ private Formula formula;
+ private Table table;
+
+ public void setTable(Table table) {
+ this.table = table;
+ }
+
+ public String getLogicalColumnName() {
+ return logicalColumnName;
+ }
+
+ public String getSqlType() {
+ return sqlType;
+ }
+
+ public int getLength() {
+ return length;
+ }
+
+ public int getPrecision() {
+ return precision;
+ }
+
+ public int getScale() {
+ return scale;
+ }
+
+ public boolean isUnique() {
+ return unique;
+ }
+
+ public boolean isFormula() {
+ return StringHelper.isNotEmpty(formulaString) ? true : false;
+ }
+
+ public String getFormulaString() {
+ return formulaString;
+ }
+
+ public String getSecondaryTableName() {
+ return secondaryTableName;
+ }
+
+ public void setFormula(String formula) {
+ this.formulaString = formula;
+ }
+
+ public boolean isImplicit() {
+ return isImplicit;
+ }
+
+ public void setInsertable(boolean insertable) {
+ this.insertable = insertable;
+ }
+
+ public void setUpdatable(boolean updatable) {
+ this.updatable = updatable;
+ }
+
+ protected ExtendedMappings getMappings() {
+ return mappings;
+ }
+
+ public void setMappings(ExtendedMappings mappings) {
+ this.mappings = mappings;
+ }
+
+ public void setImplicit(boolean implicit) {
+ isImplicit = implicit;
+ }
+
+ public void setSqlType(String sqlType) {
+ this.sqlType = sqlType;
+ }
+
+ public void setLength(int length) {
+ this.length = length;
+ }
+
+ public void setPrecision(int precision) {
+ this.precision = precision;
+ }
+
+ public void setScale(int scale) {
+ this.scale = scale;
+ }
+
+ public void setLogicalColumnName(String logicalColumnName) {
+ this.logicalColumnName = logicalColumnName;
+ }
+
+ public void setPropertyName(String propertyName) {
+ this.propertyName = propertyName;
+ }
+
+ public String getPropertyName() {
+ return propertyName;
+ }
+
+ public void setUnique(boolean unique) {
+ this.unique = unique;
+ }
+
+ public boolean isNullable() {
+ return mappingColumn.isNullable();
+ }
+
+ public Ejb3Column() {
+ }
+
+ public void bind() {
+ if ( StringHelper.isNotEmpty( formulaString ) ) {
+ log.debug( "binding formula {}", formulaString );
+ formula = new Formula();
+ formula.setFormula( formulaString );
+ }
+ else {
+ initMappingColumn(
+ logicalColumnName, propertyName, length, precision, scale, nullable, sqlType,
unique, true
+ );
+ log.debug( "Binding column: " + toString());
+ }
+ }
+
+ protected void initMappingColumn(
+ String columnName,
+ String propertyName,
+ int length,
+ int precision,
+ int scale,
+ boolean nullable,
+ String sqlType,
+ boolean unique,
+ boolean applyNamingStrategy) {
+ if ( StringHelper.isNotEmpty( formulaString ) ) {
+ this.formula = new Formula();
+ this.formula.setFormula( formulaString );
+ }
+ else {
+ this.mappingColumn = new Column();
+ redefineColumnName( columnName, propertyName, applyNamingStrategy );
+ this.mappingColumn.setLength( length );
+ if ( precision > 0 ) { //revelent precision
+ this.mappingColumn.setPrecision( precision );
+ this.mappingColumn.setScale( scale );
+ }
+ this.mappingColumn.setNullable( nullable );
+ this.mappingColumn.setSqlType( sqlType );
+ this.mappingColumn.setUnique( unique );
+ }
+ }
+
+ public boolean isNameDeferred() {
+ return mappingColumn == null || StringHelper.isEmpty( mappingColumn.getName() );
+ }
+
+ public void redefineColumnName(String columnName, String propertyName, boolean
applyNamingStrategy) {
+ if ( applyNamingStrategy ) {
+ if ( StringHelper.isEmpty( columnName ) ) {
+ if ( propertyName != null ) {
+ mappingColumn.setName(
+ mappings.getObjectNameNormalizer().normalizeIdentifierQuoting(
+ mappings.getNamingStrategy().propertyToColumnName( propertyName )
+ )
+ );
+ }
+ //Do nothing otherwise
+ }
+ else {
+ columnName = mappings.getObjectNameNormalizer().normalizeIdentifierQuoting(
columnName );
+ columnName = mappings.getNamingStrategy().columnName( columnName );
+ columnName = mappings.getObjectNameNormalizer().normalizeIdentifierQuoting(
columnName );
+ mappingColumn.setName( columnName );
+ }
+ }
+ else {
+ if ( StringHelper.isNotEmpty( columnName ) ) {
+ mappingColumn.setName( mappings.getObjectNameNormalizer().normalizeIdentifierQuoting(
columnName ) );
+ }
+ }
+ }
+
+ public String getName() {
+ return mappingColumn.getName();
+ }
+
+ public Column getMappingColumn() {
+ return mappingColumn;
+ }
+
+ public boolean isInsertable() {
+ return insertable;
+ }
+
+ public boolean isUpdatable() {
+ return updatable;
+ }
+
+ public void setNullable(boolean nullable) {
+ if ( mappingColumn != null ) {
+ mappingColumn.setNullable( nullable );
+ }
+ else {
+ this.nullable = nullable;
+ }
+ }
+
+ public void setJoins(Map<String, Join> joins) {
+ this.joins = joins;
+ }
+
+ public PropertyHolder getPropertyHolder() {
+ return propertyHolder;
+ }
+
+ public void setPropertyHolder(PropertyHolder propertyHolder) {
+ this.propertyHolder = propertyHolder;
+ }
+
+ protected void setMappingColumn(Column mappingColumn) {
+ this.mappingColumn = mappingColumn;
+ }
+
+ public void linkWithValue(SimpleValue value) {
+ if ( formula != null ) {
+ value.addFormula( formula );
+ }
+ else {
+ getMappingColumn().setValue( value );
+ value.addColumn( getMappingColumn() );
+ value.getTable().addColumn( getMappingColumn() );
+ addColumnBinding( value );
+ table = value.getTable();
+ }
+ }
+
+ protected void addColumnBinding(SimpleValue value) {
+ String logicalColumnName = mappings.getNamingStrategy()
+ .logicalColumnName( this.logicalColumnName, propertyName );
+ mappings.addColumnBinding( logicalColumnName, getMappingColumn(), value.getTable() );
+ }
+
+ /**
+ * Find appropriate table of the column.
+ * It can come from a secondary table or from the main table of the persistent class
+ *
+ * @return appropriate table
+ * @throws AnnotationException missing secondary table
+ */
+ public Table getTable() {
+ if ( table != null ) return table; //association table
+ if ( isSecondary() ) {
+ return getJoin().getTable();
+ }
+ else {
+ return propertyHolder.getTable();
+ }
+ }
+
+ public boolean isSecondary() {
+ if ( propertyHolder == null ) {
+ throw new AssertionFailure( "Should not call getTable() on column wo persistent
class defined" );
+ }
+ if ( StringHelper.isNotEmpty( secondaryTableName ) ) {
+ return true;
+ }
+ // else {
+ return false;
+ }
+
+ public Join getJoin() {
+ Join join = joins.get( secondaryTableName );
+ if ( join == null ) {
+ throw new AnnotationException(
+ "Cannot find the expected secondary table: no "
+ + secondaryTableName + " available for " +
propertyHolder.getClassName()
+ );
+ }
+ else {
+ return join;
+ }
+ }
+
+ public void forceNotNull() {
+ mappingColumn.setNullable( false );
+ }
+
+ public void setSecondaryTableName(String secondaryTableName) {
+ if ( "``".equals( secondaryTableName ) ) {
+ this.secondaryTableName = "";
+ }
+ else {
+ this.secondaryTableName = secondaryTableName;
+ }
+ }
+
+ public static Ejb3Column[] buildColumnFromAnnotation(
+ javax.persistence.Column[] anns,
+ org.hibernate.annotations.Formula formulaAnn, Nullability nullability, PropertyHolder
propertyHolder,
+ PropertyData inferredData,
+ Map<String, Join> secondaryTables,
+ ExtendedMappings mappings
+ ){
+ return buildColumnFromAnnotation(
+ anns,
+ formulaAnn, nullability, propertyHolder, inferredData, null, secondaryTables,
mappings);
+ }
+ public static Ejb3Column[] buildColumnFromAnnotation(
+ javax.persistence.Column[] anns,
+ org.hibernate.annotations.Formula formulaAnn, Nullability nullability, PropertyHolder
propertyHolder,
+ PropertyData inferredData,
+ String suffixForDefaultColumnName,
+ Map<String, Join> secondaryTables,
+ ExtendedMappings mappings
+ ) {
+ Ejb3Column[] columns;
+ if ( formulaAnn != null ) {
+ Ejb3Column formulaColumn = new Ejb3Column();
+ formulaColumn.setFormula( formulaAnn.value() );
+ formulaColumn.setImplicit( false );
+ formulaColumn.setMappings( mappings );
+ formulaColumn.setPropertyHolder( propertyHolder );
+ formulaColumn.bind();
+ columns = new Ejb3Column[] { formulaColumn };
+ }
+ else {
+ javax.persistence.Column[] actualCols = anns;
+ javax.persistence.Column[] overriddenCols = propertyHolder.getOverriddenColumn(
+ StringHelper.qualify( propertyHolder.getPath(), inferredData.getPropertyName() )
+ );
+ if ( overriddenCols != null ) {
+ //check for overridden first
+ if ( anns != null && overriddenCols.length != anns.length ) {
+ throw new AnnotationException( "AttributeOverride.column() should override all
columns for now" );
+ }
+ actualCols = overriddenCols.length == 0 ? null : overriddenCols;
+ log.debug( "Column(s) overridden for property {}",
inferredData.getPropertyName() );
+ }
+ if ( actualCols == null ) {
+ columns = buildImplicitColumn(
+ inferredData,
+ suffixForDefaultColumnName,
+ secondaryTables,
+ propertyHolder,
+ nullability,
+ mappings
+ );
+ }
+ else {
+ final int length = actualCols.length;
+ columns = new Ejb3Column[length];
+ for (int index = 0; index < length; index++) {
+ final ObjectNameNormalizer nameNormalizer = mappings.getObjectNameNormalizer();
+ javax.persistence.Column col = actualCols[index];
+ final String sqlType = col.columnDefinition().equals( "" )
+ ? null
+ : nameNormalizer.normalizeIdentifierQuoting( col.columnDefinition() );
+ final String tableName = nameNormalizer.normalizeIdentifierQuoting( col.table() );
+ final String columnName = nameNormalizer.normalizeIdentifierQuoting( col.name() );
+ Ejb3Column column = new Ejb3Column();
+ column.setImplicit( false );
+ column.setSqlType( sqlType );
+ column.setLength( col.length() );
+ column.setPrecision( col.precision() );
+ column.setScale( col.scale() );
+ if ( StringHelper.isEmpty( columnName ) && ! StringHelper.isEmpty(
suffixForDefaultColumnName ) ) {
+ column.setLogicalColumnName( inferredData.getPropertyName() +
suffixForDefaultColumnName );
+ }
+ else {
+ column.setLogicalColumnName( columnName );
+ }
+
+ column.setPropertyName(
+ BinderHelper.getRelativePath( propertyHolder, inferredData.getPropertyName() )
+ );
+ column.setNullable(
+ col.nullable()
+ ); //TODO force to not null if available? This is a (bad) user choice.
+ column.setUnique( col.unique() );
+ column.setInsertable( col.insertable() );
+ column.setUpdatable( col.updatable() );
+ column.setSecondaryTableName( tableName );
+ column.setPropertyHolder( propertyHolder );
+ column.setJoins( secondaryTables );
+ column.setMappings( mappings );
+ column.bind();
+ columns[index] = column;
+ }
+ }
+ }
+ return columns;
+ }
+
+ private static Ejb3Column[] buildImplicitColumn(
+ PropertyData inferredData,
+ String suffixForDefaultColumnName,
+ Map<String, Join> secondaryTables,
+ PropertyHolder propertyHolder,
+ Nullability nullability,
+ ExtendedMappings mappings) {
+ Ejb3Column column = new Ejb3Column();
+ Ejb3Column[] columns = new Ejb3Column[1];
+ columns[0] = column;
+
+ //not following the spec but more clean
+ if ( nullability != Nullability.FORCED_NULL
+ && inferredData.getClassOrElement().isPrimitive()
+ && !inferredData.getProperty().isArray() ) {
+ column.setNullable( false );
+ }
+ column.setLength( DEFAULT_COLUMN_LENGTH );
+ final String propertyName = inferredData.getPropertyName();
+ column.setPropertyName(
+ BinderHelper.getRelativePath( propertyHolder, propertyName )
+ );
+ column.setPropertyHolder( propertyHolder );
+ column.setJoins( secondaryTables );
+ column.setMappings( mappings );
+
+ // property name + suffix is an "explicit" column name
+ if ( !StringHelper.isEmpty( suffixForDefaultColumnName ) ) {
+ column.setLogicalColumnName( propertyName + suffixForDefaultColumnName );
+ column.setImplicit( false );
+ }
+ else {
+ column.setImplicit( true );
+ }
+ column.bind();
+ return columns;
+ }
+
+ public static void checkPropertyConsistency(Ejb3Column[] columns, String propertyName)
{
+ int nbrOfColumns = columns.length;
+
+ if ( nbrOfColumns > 1 ) {
+ for (int currentIndex = 1; currentIndex < nbrOfColumns; currentIndex++) {
+
+ if (columns[currentIndex].isFormula() || columns[currentIndex - 1].isFormula()) {
+ continue;
+ }
+
+ if ( columns[currentIndex].isInsertable() != columns[currentIndex - 1].isInsertable()
) {
+ throw new AnnotationException(
+ "Mixing insertable and non insertable columns in a property is not allowed:
" + propertyName
+ );
+ }
+ if ( columns[currentIndex].isNullable() != columns[currentIndex - 1].isNullable() )
{
+ throw new AnnotationException(
+ "Mixing nullable and non nullable columns in a property is not allowed:
" + propertyName
+ );
+ }
+ if ( columns[currentIndex].isUpdatable() != columns[currentIndex - 1].isUpdatable() )
{
+ throw new AnnotationException(
+ "Mixing updatable and non updatable columns in a property is not allowed:
" + propertyName
+ );
+ }
+ if ( !columns[currentIndex].getTable().equals( columns[currentIndex - 1].getTable() )
) {
+ throw new AnnotationException(
+ "Mixing different tables in a property is not allowed: " + propertyName
+ );
+ }
+ }
+ }
+
+ }
+
+ public void addIndex(Index index, boolean inSecondPass) {
+ if ( index == null ) return;
+ String indexName = index.name();
+ addIndex( indexName, inSecondPass );
+ }
+
+ void addIndex(String indexName, boolean inSecondPass) {
+ IndexOrUniqueKeySecondPass secondPass = new IndexOrUniqueKeySecondPass( indexName,
this, mappings, false );
+ if ( inSecondPass ) {
+ secondPass.doSecondPass( mappings.getClasses() );
+ }
+ else {
+ mappings.addSecondPass(
+ secondPass
+ );
+ }
+ }
+
+ void addUniqueKey(String uniqueKeyName, boolean inSecondPass) {
+ IndexOrUniqueKeySecondPass secondPass = new IndexOrUniqueKeySecondPass( uniqueKeyName,
this, mappings, true );
+ if ( inSecondPass ) {
+ secondPass.doSecondPass( mappings.getClasses() );
+ }
+ else {
+ mappings.addSecondPass(
+ secondPass
+ );
+ }
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append( "Ejb3Column" );
+ sb.append( "{table=" ).append( getTable() );
+ sb.append( ", mappingColumn=" ).append( mappingColumn.getName() );
+ sb.append( ", insertable=" ).append( insertable );
+ sb.append( ", updatable=" ).append( updatable );
+ sb.append( ", unique=" ).append( unique );
+ sb.append( '}' );
+ return sb.toString();
+ }
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/cfg/Ejb3Column.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/Ejb3DiscriminatorColumn.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/Ejb3DiscriminatorColumn.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/Ejb3DiscriminatorColumn.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/Ejb3DiscriminatorColumn.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,114 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.DiscriminatorType;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.annotations.DiscriminatorFormula;
+
+/**
+ * Discriminator column
+ *
+ * @author Emmanuel Bernard
+ */
+public class Ejb3DiscriminatorColumn extends Ejb3Column {
+
+
+ private static final String DEFAULT_DISCRIMINATOR_COLUMN_NAME = "DTYPE";
+ private static final String DEFAULT_DISCRIMINATOR_TYPE = "string";
+
+ private String discriminatorTypeName;
+ private static final int DEFAULT_DISCRIMINATOR_LENGTH = 31;
+
+ public Ejb3DiscriminatorColumn() {
+ //discriminator default value
+ super();
+ setLogicalColumnName( DEFAULT_DISCRIMINATOR_COLUMN_NAME );
+ setNullable( false );
+ setDiscriminatorTypeName( DEFAULT_DISCRIMINATOR_TYPE );
+ setLength( DEFAULT_DISCRIMINATOR_LENGTH );
+ }
+
+ public String getDiscriminatorTypeName() {
+ return discriminatorTypeName;
+ }
+
+ public void setDiscriminatorTypeName(String discriminatorTypeName) {
+ this.discriminatorTypeName = discriminatorTypeName;
+ }
+
+ public static Ejb3DiscriminatorColumn buildDiscriminatorColumn(
+ DiscriminatorType type, DiscriminatorColumn discAnn, DiscriminatorFormula
discFormulaAnn,
+ ExtendedMappings mappings
+ ) {
+ Ejb3DiscriminatorColumn discriminatorColumn = new Ejb3DiscriminatorColumn();
+ discriminatorColumn.setMappings( mappings );
+ discriminatorColumn.setImplicit( true );
+ if ( discFormulaAnn != null ) {
+ discriminatorColumn.setImplicit( false );
+ discriminatorColumn.setFormula( discFormulaAnn.value() );
+ }
+ else if ( discAnn != null ) {
+ discriminatorColumn.setImplicit( false );
+ if ( !BinderHelper.isDefault( discAnn.columnDefinition() ) ) {
+ discriminatorColumn.setSqlType(
+ discAnn.columnDefinition()
+ );
+ }
+ if ( !BinderHelper.isDefault( discAnn.name() ) ) {
+ discriminatorColumn.setLogicalColumnName( discAnn.name() );
+ }
+ discriminatorColumn.setNullable( false );
+ }
+ if ( DiscriminatorType.CHAR.equals( type ) ) {
+ discriminatorColumn.setDiscriminatorTypeName( "character" );
+ discriminatorColumn.setImplicit( false );
+ }
+ else if ( DiscriminatorType.INTEGER.equals( type ) ) {
+ discriminatorColumn.setDiscriminatorTypeName( "integer" );
+ discriminatorColumn.setImplicit( false );
+ }
+ else if ( DiscriminatorType.STRING.equals( type ) || type == null ) {
+ if ( discAnn != null ) discriminatorColumn.setLength( discAnn.length() );
+ discriminatorColumn.setDiscriminatorTypeName( "string" );
+ }
+ else {
+ throw new AssertionFailure( "Unknown discriminator type: " + type );
+ }
+ discriminatorColumn.bind();
+ return discriminatorColumn;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append( "Ejb3DiscriminatorColumn" );
+ sb.append( "{logicalColumnName'" ).append( getLogicalColumnName()
).append( '\'' );
+ sb.append( ", discriminatorTypeName='" ).append( discriminatorTypeName
).append( '\'' );
+ sb.append( '}' );
+ return sb.toString();
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/Ejb3DiscriminatorColumn.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,697 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import javax.persistence.JoinColumn;
+import javax.persistence.PrimaryKeyJoinColumn;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.AssertionFailure;
+import org.hibernate.MappingException;
+import org.hibernate.util.StringHelper;
+import org.hibernate.annotations.JoinColumnOrFormula;
+import org.hibernate.annotations.JoinColumnsOrFormulas;
+import org.hibernate.annotations.JoinFormula;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.Join;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.SimpleValue;
+import org.hibernate.mapping.Table;
+import org.hibernate.mapping.Value;
+
+/**
+ * Wrap state of an EJB3 @JoinColumn annotation
+ * and build the Hibernate column mapping element
+ *
+ * @author Emmanuel Bernard
+ */
+@SuppressWarnings("unchecked")
+public class Ejb3JoinColumn extends Ejb3Column {
+ /**
+ * property name repated to this column
+ */
+ private String referencedColumn;
+ private String mappedBy;
+ //property name on the mapped by side if any
+ private String mappedByPropertyName;
+ //table name on the mapped by side if any
+ private String mappedByTableName;
+ private String mappedByEntityName;
+ private boolean JPA2ElementCollection;
+
+ public void setJPA2ElementCollection(boolean JPA2ElementCollection) {
+ this.JPA2ElementCollection = JPA2ElementCollection;
+ }
+
+ //FIXME hacky solution to get the information at property ref resolution
+ public String getManyToManyOwnerSideEntityName() {
+ return manyToManyOwnerSideEntityName;
+ }
+
+ public void setManyToManyOwnerSideEntityName(String manyToManyOwnerSideEntityName) {
+ this.manyToManyOwnerSideEntityName = manyToManyOwnerSideEntityName;
+ }
+
+ private String manyToManyOwnerSideEntityName;
+
+ public void setReferencedColumn(String referencedColumn) {
+ this.referencedColumn = referencedColumn;
+ }
+
+ public String getMappedBy() {
+ return mappedBy;
+ }
+
+ public void setMappedBy(String mappedBy) {
+ this.mappedBy = mappedBy;
+ }
+
+ //Due to @AnnotationOverride overriding rules, I don't want the constructor to be
public
+ private Ejb3JoinColumn() {
+ setMappedBy( BinderHelper.ANNOTATION_STRING_DEFAULT );
+ }
+
+ //Due to @AnnotationOverride overriding rules, I don't want the constructor to be
public
+ //TODO get rid of it and use setters
+ private Ejb3JoinColumn(
+ String sqlType,
+ String name,
+ boolean nullable,
+ boolean unique,
+ boolean insertable,
+ boolean updatable,
+ String referencedColumn,
+ String secondaryTable,
+ Map<String, Join> joins,
+ PropertyHolder propertyHolder,
+ String propertyName,
+ String mappedBy,
+ boolean isImplicit,
+ ExtendedMappings mappings
+ ) {
+ super();
+ setImplicit( isImplicit );
+ setSqlType( sqlType );
+ setLogicalColumnName( name );
+ setNullable( nullable );
+ setUnique( unique );
+ setInsertable( insertable );
+ setUpdatable( updatable );
+ setSecondaryTableName( secondaryTable );
+ setPropertyHolder( propertyHolder );
+ setJoins( joins );
+ setMappings( mappings );
+ setPropertyName( BinderHelper.getRelativePath( propertyHolder, propertyName ) );
+ bind();
+ this.referencedColumn = referencedColumn;
+ this.mappedBy = mappedBy;
+ }
+
+ public String getReferencedColumn() {
+ return referencedColumn;
+ }
+
+
+ public static Ejb3JoinColumn[] buildJoinColumnsOrFormulas(
+ JoinColumnsOrFormulas anns,
+ String mappedBy, Map<String, Join> joins,
+ PropertyHolder propertyHolder,
+ String propertyName,
+ ExtendedMappings mappings
+ ) {
+
+ JoinColumnOrFormula [] ann = anns.value();
+ Ejb3JoinColumn [] joinColumns = new Ejb3JoinColumn[ann.length];
+ for (int i = 0; i < ann.length; i++) {
+ JoinColumnOrFormula join = (JoinColumnOrFormula) ann[i];
+ JoinFormula formula = join.formula();
+ if (formula.value() != null && !formula.value().equals("")) {
+ joinColumns[i] = buildJoinFormula(formula, mappedBy, joins, propertyHolder,
propertyName, mappings);
+ }
+ else {
+ joinColumns[i] = buildJoinColumns(new JoinColumn[] { join.column() }, mappedBy,
joins, propertyHolder, propertyName, mappings)[0];
+ }
+ }
+
+ return joinColumns;
+ }
+
+ /**
+ * build join formula
+ */
+ public static Ejb3JoinColumn buildJoinFormula(
+ JoinFormula ann,
+ String mappedBy, Map<String, Join> joins,
+ PropertyHolder propertyHolder,
+ String propertyName,
+ ExtendedMappings mappings
+ ) {
+
+ Ejb3JoinColumn formulaColumn = new Ejb3JoinColumn();
+ formulaColumn.setFormula( ann.value() );
+ formulaColumn.setReferencedColumn(ann.referencedColumnName());
+ formulaColumn.setMappings( mappings );
+ formulaColumn.setPropertyHolder( propertyHolder );
+ formulaColumn.setJoins( joins );
+ formulaColumn.setPropertyName( BinderHelper.getRelativePath( propertyHolder,
propertyName ) );
+
+ formulaColumn.bind();
+ return formulaColumn;
+ }
+
+
+ public static Ejb3JoinColumn[] buildJoinColumns(
+ JoinColumn[] anns,
+ String mappedBy, Map<String, Join> joins,
+ PropertyHolder propertyHolder,
+ String propertyName,
+ ExtendedMappings mappings
+ ) {
+ return buildJoinColumnsWithDefaultColumnSuffix(anns, mappedBy, joins, propertyHolder,
propertyName, "", mappings);
+ }
+
+ public static Ejb3JoinColumn[] buildJoinColumnsWithDefaultColumnSuffix(
+ JoinColumn[] anns,
+ String mappedBy, Map<String, Join> joins,
+ PropertyHolder propertyHolder,
+ String propertyName,
+ String suffixForDefaultColumnName,
+ ExtendedMappings mappings
+ ) {
+ JoinColumn[] actualColumns = propertyHolder.getOverriddenJoinColumn(
+ StringHelper.qualify( propertyHolder.getPath(), propertyName )
+ );
+ if ( actualColumns == null ) actualColumns = anns;
+ if ( actualColumns == null || actualColumns.length == 0 ) {
+ return new Ejb3JoinColumn[] {
+ buildJoinColumn(
+ (JoinColumn) null,
+ mappedBy,
+ joins,
+ propertyHolder,
+ propertyName,
+ suffixForDefaultColumnName,
+ mappings )
+ };
+ }
+ else {
+ int size = actualColumns.length;
+ Ejb3JoinColumn[] result = new Ejb3JoinColumn[size];
+ for (int index = 0; index < size; index++) {
+ result[index] = buildJoinColumn(
+ actualColumns[index],
+ mappedBy,
+ joins,
+ propertyHolder,
+ propertyName,
+ suffixForDefaultColumnName,
+ mappings
+ );
+ }
+ return result;
+ }
+ }
+
+ /**
+ * build join column for SecondaryTables
+ */
+ private static Ejb3JoinColumn buildJoinColumn(
+ JoinColumn ann,
+ String mappedBy, Map<String, Join> joins,
+ PropertyHolder propertyHolder,
+ String propertyName,
+ String suffixForDefaultColumnName,
+ ExtendedMappings mappings
+ ) {
+ if ( ann != null ) {
+ if ( BinderHelper.isDefault( mappedBy ) ) {
+ throw new AnnotationException(
+ "Illegal attempt to define a @JoinColumn with a mappedBy association: "
+ + BinderHelper.getRelativePath( propertyHolder, propertyName )
+ );
+ }
+ Ejb3JoinColumn joinColumn = new Ejb3JoinColumn();
+ joinColumn.setJoinAnnotation( ann, null );
+ if ( StringHelper.isEmpty( joinColumn.getLogicalColumnName() )
+ && ! StringHelper.isEmpty( suffixForDefaultColumnName ) ) {
+ joinColumn.setLogicalColumnName( propertyName + suffixForDefaultColumnName );
+ }
+ joinColumn.setJoins( joins );
+ joinColumn.setPropertyHolder( propertyHolder );
+ joinColumn.setPropertyName( BinderHelper.getRelativePath( propertyHolder, propertyName
) );
+ joinColumn.setImplicit( false );
+ joinColumn.setMappings( mappings );
+ joinColumn.bind();
+ return joinColumn;
+ }
+ else {
+ Ejb3JoinColumn joinColumn = new Ejb3JoinColumn();
+ joinColumn.setMappedBy( mappedBy );
+ joinColumn.setJoins( joins );
+ joinColumn.setPropertyHolder( propertyHolder );
+ joinColumn.setPropertyName(
+ BinderHelper.getRelativePath( propertyHolder, propertyName )
+ );
+ // property name + suffix is an "explicit" column name
+ if ( !StringHelper.isEmpty( suffixForDefaultColumnName ) ) {
+ joinColumn.setLogicalColumnName( propertyName + suffixForDefaultColumnName );
+ joinColumn.setImplicit( false );
+ }
+ else {
+ joinColumn.setImplicit( true );
+ }
+ joinColumn.setMappings( mappings );
+ joinColumn.bind();
+ return joinColumn;
+ }
+ }
+
+
+ //FIXME default name still useful in association table
+ public void setJoinAnnotation(JoinColumn annJoin, String defaultName) {
+ if ( annJoin == null ) {
+ setImplicit( true );
+ }
+ else {
+ setImplicit( false );
+ if ( !BinderHelper.isDefault( annJoin.columnDefinition() ) ) setSqlType(
annJoin.columnDefinition() );
+ if ( !BinderHelper.isDefault( annJoin.name() ) ) setLogicalColumnName( annJoin.name()
);
+ setNullable( annJoin.nullable() );
+ setUnique( annJoin.unique() );
+ setInsertable( annJoin.insertable() );
+ setUpdatable( annJoin.updatable() );
+ setReferencedColumn( annJoin.referencedColumnName() );
+ setSecondaryTableName( annJoin.table() );
+ }
+ }
+
+ /**
+ * Build JoinColumn for a JOINED hierarchy
+ */
+ public static Ejb3JoinColumn buildJoinColumn(
+ PrimaryKeyJoinColumn pkJoinAnn,
+ JoinColumn joinAnn,
+ Value identifier,
+ Map<String, Join> joins,
+ PropertyHolder propertyHolder, ExtendedMappings mappings
+ ) {
+
+ Column col = (Column) identifier.getColumnIterator().next();
+ String defaultName = mappings.getLogicalColumnName( col.getQuotedName(),
identifier.getTable() );
+ if ( pkJoinAnn != null || joinAnn != null ) {
+ String colName;
+ String columnDefinition;
+ String referencedColumnName;
+ if ( pkJoinAnn != null ) {
+ colName = pkJoinAnn.name();
+ columnDefinition = pkJoinAnn.columnDefinition();
+ referencedColumnName = pkJoinAnn.referencedColumnName();
+ }
+ else {
+ colName = joinAnn.name();
+ columnDefinition = joinAnn.columnDefinition();
+ referencedColumnName = joinAnn.referencedColumnName();
+ }
+
+ String sqlType = "".equals( columnDefinition )
+ ? null
+ : mappings.getObjectNameNormalizer().normalizeIdentifierQuoting( columnDefinition
);
+ String name = "".equals( colName )
+ ? defaultName
+ : colName;
+ name = mappings.getObjectNameNormalizer().normalizeIdentifierQuoting( name );
+ return new Ejb3JoinColumn(
+ sqlType,
+ name, false, false,
+ true, true,
+ referencedColumnName,
+ null, joins,
+ propertyHolder, null, null, false, mappings
+ );
+ }
+ else {
+ defaultName = mappings.getObjectNameNormalizer().normalizeIdentifierQuoting(
defaultName );
+ return new Ejb3JoinColumn(
+ (String) null, defaultName,
+ false, false, true, true, null, (String) null,
+ joins, propertyHolder, null, null, true, mappings
+ );
+ }
+ }
+
+ /**
+ * Override persistent class on oneToMany Cases for late settings
+ * Must only be used on second level pass binding
+ */
+ public void setPersistentClass(PersistentClass persistentClass,
+ Map<String, Join> joins,
+ Map<XClass, InheritanceState> inheritanceStatePerClass) {
+ //FIXME shouldn't we deduce the classname from the persistentclasS?
+ this.propertyHolder = PropertyHolderBuilder.buildPropertyHolder( persistentClass,
joins, getMappings(), inheritanceStatePerClass );
+ }
+
+ public static void checkIfJoinColumn(Object columns, PropertyHolder holder, PropertyData
property) {
+ if ( !( columns instanceof Ejb3JoinColumn[] ) ) {
+ throw new AnnotationException(
+ "@Column cannot be used on an association property: "
+ + holder.getEntityName()
+ + "."
+ + property.getPropertyName()
+ );
+ }
+ }
+
+
+
+ public void copyReferencedStructureAndCreateDefaultJoinColumns(
+ PersistentClass referencedEntity, Iterator columnIterator, SimpleValue value
+ ) {
+ if ( !isNameDeferred() ) {
+ throw new AssertionFailure( "Building implicit column but the column is not
implicit" );
+ }
+ while ( columnIterator.hasNext() ) {
+ Column synthCol = (Column) columnIterator.next();
+ this.linkValueUsingDefaultColumnNaming( synthCol, referencedEntity, value );
+ }
+ //reset for the future
+ setMappingColumn( null );
+ }
+
+ public void linkValueUsingDefaultColumnNaming(
+ Column referencedColumn, PersistentClass referencedEntity, SimpleValue value
+ ) {
+ String columnName;
+ String logicalReferencedColumn = getMappings().getLogicalColumnName(
+ referencedColumn.getQuotedName(), referencedEntity.getTable()
+ );
+ columnName = buildDefaultColumnName( referencedEntity, logicalReferencedColumn );
+ //yuk side effect on an implicit column
+ setLogicalColumnName( columnName );
+ setReferencedColumn( logicalReferencedColumn );
+ initMappingColumn(
+ columnName,
+ null, referencedColumn.getLength(),
+ referencedColumn.getPrecision(),
+ referencedColumn.getScale(),
+ getMappingColumn() != null ? getMappingColumn().isNullable() : false,
+ referencedColumn.getSqlType(),
+ getMappingColumn() != null ? getMappingColumn().isUnique() : false,
+ false
+ );
+ linkWithValue( value );
+ }
+
+ public void addDefaultJoinColumnName(PersistentClass referencedEntity, String
logicalReferencedColumn) {
+ final String columnName = buildDefaultColumnName( referencedEntity,
logicalReferencedColumn );
+ getMappingColumn().setName( columnName );
+ setLogicalColumnName( columnName );
+ }
+
+ private String buildDefaultColumnName(PersistentClass referencedEntity, String
logicalReferencedColumn) {
+ String columnName;
+ boolean mappedBySide = mappedByTableName != null || mappedByPropertyName != null;
+ boolean ownerSide = getPropertyName() != null;
+
+ Boolean isRefColumnQuoted = StringHelper.isQuoted( logicalReferencedColumn );
+ String unquotedLogicalReferenceColumn = isRefColumnQuoted ?
+ StringHelper.unquote( logicalReferencedColumn ) :
+ logicalReferencedColumn;
+
+ if ( mappedBySide ) {
+ String unquotedMappedbyTable = StringHelper.unquote( mappedByTableName );
+ final String ownerObjectName = JPA2ElementCollection && mappedByEntityName !=
null ?
+ StringHelper.unqualify( mappedByEntityName ) : unquotedMappedbyTable;
+ columnName = getMappings().getNamingStrategy().foreignKeyColumnName(
+ mappedByPropertyName,
+ mappedByEntityName,
+ ownerObjectName,
+ unquotedLogicalReferenceColumn
+ );
+ //one element was quoted so we quote
+ if ( isRefColumnQuoted || StringHelper.isQuoted( mappedByTableName ) ) {
+ columnName = StringHelper.quote( columnName );
+ }
+ }
+ else if ( ownerSide ) {
+ String logicalTableName = getMappings().getLogicalTableName(
referencedEntity.getTable() );
+ String unquotedLogicalTableName = StringHelper.unquote( logicalTableName );
+ columnName = getMappings().getNamingStrategy().foreignKeyColumnName(
+ getPropertyName(),
+ referencedEntity.getEntityName(),
+ unquotedLogicalTableName,
+ unquotedLogicalReferenceColumn
+ );
+ //one element was quoted so we quote
+ if ( isRefColumnQuoted || StringHelper.isQuoted( logicalTableName ) ) {
+ columnName = StringHelper.quote( columnName );
+ }
+ }
+ else {
+ //is an intra-entity hierarchy table join so copy the name by default
+ String logicalTableName = getMappings().getLogicalTableName(
referencedEntity.getTable() );
+ String unquotedLogicalTableName = StringHelper.unquote( logicalTableName );
+ columnName = getMappings().getNamingStrategy().joinKeyColumnName(
+ unquotedLogicalReferenceColumn,
+ unquotedLogicalTableName
+ );
+ //one element was quoted so we quote
+ if ( isRefColumnQuoted || StringHelper.isQuoted( logicalTableName ) ) {
+ columnName = StringHelper.quote( columnName );
+ }
+ }
+ return columnName;
+ }
+
+ /**
+ * used for mappedBy cases
+ */
+ public void linkValueUsingAColumnCopy(Column column, SimpleValue value) {
+ initMappingColumn(
+ //column.getName(),
+ column.getQuotedName(),
+ null, column.getLength(),
+ column.getPrecision(),
+ column.getScale(),
+ getMappingColumn().isNullable(),
+ column.getSqlType(),
+ getMappingColumn().isUnique(),
+ false //We do copy no strategy here
+ );
+ linkWithValue( value );
+ }
+
+ protected void addColumnBinding(SimpleValue value) {
+ if ( StringHelper.isEmpty( mappedBy ) ) {
+ String unquotedLogColName = StringHelper.unquote( getLogicalColumnName() );
+ String unquotedRefColumn = StringHelper.unquote( getReferencedColumn() );
+ String logicalColumnName = getMappings().getNamingStrategy()
+ .logicalCollectionColumnName( unquotedLogColName, getPropertyName(),
unquotedRefColumn );
+ if ( StringHelper.isQuoted( getLogicalColumnName() ) || StringHelper.isQuoted(
getLogicalColumnName() ) ) {
+ logicalColumnName = StringHelper.quote( logicalColumnName );
+ }
+ getMappings().addColumnBinding( logicalColumnName, getMappingColumn(),
value.getTable() );
+ }
+ }
+
+ //keep it JDK 1.4 compliant
+ //implicit way
+ public static final int NO_REFERENCE = 0;
+ //reference to the pk in an explicit order
+ public static final int PK_REFERENCE = 1;
+ //reference to non pk columns
+ public static final int NON_PK_REFERENCE = 2;
+
+ public static int checkReferencedColumnsType(
+ Ejb3JoinColumn[] columns, PersistentClass referencedEntity,
+ ExtendedMappings mappings
+ ) {
+ //convenient container to find whether a column is an id one or not
+ Set<Column> idColumns = new HashSet<Column>();
+ Iterator idColumnsIt = referencedEntity.getKey().getColumnIterator();
+ while ( idColumnsIt.hasNext() ) {
+ idColumns.add( (Column) idColumnsIt.next() );
+ }
+
+ boolean isFkReferencedColumnName = false;
+ boolean noReferencedColumn = true;
+ //build the list of potential tables
+ if ( columns.length == 0 ) return NO_REFERENCE; //shortcut
+ Object columnOwner = BinderHelper.findColumnOwner(
+ referencedEntity, columns[0].getReferencedColumn(), mappings
+ );
+ if ( columnOwner == null ) {
+ try {
+ throw new MappingException(
+ "Unable to find column with logical name: "
+ + columns[0].getReferencedColumn() + " in " +
referencedEntity.getTable() + " and its related "
+ + "supertables and secondary tables"
+ );
+ }
+ catch (MappingException e) {
+ throw new RecoverableException(e);
+ }
+ }
+ Table matchingTable = columnOwner instanceof PersistentClass ?
+ ( (PersistentClass) columnOwner ).getTable() :
+ ( (Join) columnOwner ).getTable();
+ //check each referenced column
+ for (Ejb3JoinColumn ejb3Column : columns) {
+ String logicalReferencedColumnName = ejb3Column.getReferencedColumn();
+ if ( StringHelper.isNotEmpty( logicalReferencedColumnName ) ) {
+ String referencedColumnName;
+ try {
+ referencedColumnName = mappings.getPhysicalColumnName( logicalReferencedColumnName,
matchingTable );
+ }
+ catch (MappingException me) {
+ //rewrite the exception
+ throw new MappingException(
+ "Unable to find column with logical name: "
+ + logicalReferencedColumnName + " in " + matchingTable.getName()
+ );
+ }
+ noReferencedColumn = false;
+ Column refCol = new Column( referencedColumnName );
+ boolean contains = idColumns.contains( refCol );
+ if ( !contains ) {
+ isFkReferencedColumnName = true;
+ break; //we know the state
+ }
+ }
+ }
+ if ( isFkReferencedColumnName ) {
+ return NON_PK_REFERENCE;
+ }
+ else if ( noReferencedColumn ) {
+ return NO_REFERENCE;
+ }
+ else if ( idColumns.size() != columns.length ) {
+ //reference use PK but is a subset or a superset
+ return NON_PK_REFERENCE;
+ }
+ else {
+ return PK_REFERENCE;
+ }
+ }
+
+ /**
+ * Called to apply column definitions from the referenced FK column to this column.
+ *
+ * @param column the referenced column.
+ */
+ public void overrideFromReferencedColumnIfNecessary(org.hibernate.mapping.Column column)
{
+
+ if (getMappingColumn() != null) {
+ // columnDefinition can also be specified using @JoinColumn, hence we have to check
+ // whether it is set or not
+ if ( StringHelper.isEmpty( sqlType ) ) {
+ sqlType = column.getSqlType();
+ getMappingColumn().setSqlType( sqlType );
+ }
+
+ // these properties can only be applied on the referenced column - we can just take
them over
+ getMappingColumn().setLength(column.getLength());
+ getMappingColumn().setPrecision(column.getPrecision());
+ getMappingColumn().setScale(column.getScale());
+ }
+ }
+
+ @Override
+ public void redefineColumnName(String columnName, String propertyName, boolean
applyNamingStrategy) {
+ if ( StringHelper.isNotEmpty( columnName ) ) {
+ getMappingColumn().setName(
+ applyNamingStrategy ?
+ getMappings().getNamingStrategy().columnName( columnName ) :
+ columnName
+ );
+ }
+ }
+
+ public static Ejb3JoinColumn[] buildJoinTableJoinColumns(
+ JoinColumn[] annJoins, Map<String, Join> secondaryTables,
+ PropertyHolder propertyHolder, String propertyName, String mappedBy, ExtendedMappings
mappings
+ ) {
+ Ejb3JoinColumn[] joinColumns;
+ if ( annJoins == null ) {
+ Ejb3JoinColumn currentJoinColumn = new Ejb3JoinColumn();
+ currentJoinColumn.setImplicit( true );
+ currentJoinColumn.setNullable( false ); //I break the spec, but it's for good
+ currentJoinColumn.setPropertyHolder( propertyHolder );
+ currentJoinColumn.setJoins( secondaryTables );
+ currentJoinColumn.setMappings( mappings );
+ currentJoinColumn.setPropertyName(
+ BinderHelper.getRelativePath( propertyHolder, propertyName )
+ );
+ currentJoinColumn.setMappedBy( mappedBy );
+ currentJoinColumn.bind();
+
+ joinColumns = new Ejb3JoinColumn[] {
+ currentJoinColumn
+
+ };
+ }
+ else {
+ joinColumns = new Ejb3JoinColumn[annJoins.length];
+ JoinColumn annJoin;
+ int length = annJoins.length;
+ for (int index = 0; index < length; index++) {
+ annJoin = annJoins[index];
+ Ejb3JoinColumn currentJoinColumn = new Ejb3JoinColumn();
+ currentJoinColumn.setImplicit( true );
+ currentJoinColumn.setPropertyHolder( propertyHolder );
+ currentJoinColumn.setJoins( secondaryTables );
+ currentJoinColumn.setMappings( mappings );
+ currentJoinColumn.setPropertyName( BinderHelper.getRelativePath( propertyHolder,
propertyName ) );
+ currentJoinColumn.setMappedBy( mappedBy );
+ currentJoinColumn.setJoinAnnotation( annJoin, propertyName );
+ currentJoinColumn.setNullable( false ); //I break the spec, but it's for good
+ //done after the annotation to override it
+ currentJoinColumn.bind();
+ joinColumns[index] = currentJoinColumn;
+ }
+ }
+ return joinColumns;
+ }
+
+ public void setMappedBy(String entityName, String logicalTableName, String
mappedByProperty) {
+ this.mappedByEntityName = entityName;
+ this.mappedByTableName = logicalTableName;
+ this.mappedByPropertyName = mappedByProperty;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append( "Ejb3JoinColumn" );
+ sb.append( "{logicalColumnName='" ).append( getLogicalColumnName()
).append( '\'' );
+ sb.append( ", referencedColumn='" ).append( referencedColumn ).append(
'\'' );
+ sb.append( ", mappedBy='" ).append( mappedBy ).append( '\''
);
+ sb.append( '}' );
+ return sb.toString();
+ }
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/ExtendedMappings.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/cfg/ExtendedMappings.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/ExtendedMappings.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/ExtendedMappings.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,214 @@
+// $Id$
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.MappingException;
+import org.hibernate.annotations.AnyMetaDef;
+import org.hibernate.annotations.common.reflection.ReflectionManager;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.engine.NamedQueryDefinition;
+import org.hibernate.engine.NamedSQLQueryDefinition;
+import org.hibernate.engine.ResultSetMappingDefinition;
+import org.hibernate.mapping.FetchProfile;
+import org.hibernate.mapping.IdGenerator;
+import org.hibernate.mapping.Join;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Table;
+
+/**
+ * Allow annotation related mappings
+ * <p/>
+ * at least for named generators
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+public interface ExtendedMappings extends Mappings {
+
+ /**
+ * Adds a default id generator.
+ *
+ * @param generator The id generator
+ */
+ public void addDefaultGenerator(IdGenerator generator);
+
+ /**
+ * Retrieve the id-generator by name.
+ *
+ * @param name The generator name.
+ *
+ * @return The generator, or null.
+ */
+ public IdGenerator getGenerator(String name);
+
+ /**
+ * Try to find the generator from the localGenerators
+ * and then from the global generator list
+ *
+ * @param name generator name
+ * @param localGenerators local generators
+ *
+ * @return the appropriate idgenerator or null if not found
+ */
+ public IdGenerator getGenerator(String name, Map<String, IdGenerator>
localGenerators);
+
+ /**
+ * Add a generator.
+ *
+ * @param generator The generator to add.
+ */
+ public void addGenerator(IdGenerator generator);
+
+ /**
+ * Add a generator table properties.
+ *
+ * @param name The generator name
+ * @param params The generator table properties.
+ */
+ public void addGeneratorTable(String name, Properties params);
+
+ /**
+ * Retrieve the properties related to a generator table.
+ *
+ * @param name generator name
+ * @param localGeneratorTables local generator tables
+ *
+ * @return The properties, or null.
+ */
+ public Properties getGeneratorTableProperties(String name, Map<String, Properties>
localGeneratorTables);
+
+ /**
+ * Retrieve join metadata for a particular persistent entity.
+ *
+ * @param entityName The entity name
+ *
+ * @return The join metadata
+ */
+ public Map<String, Join> getJoins(String entityName);
+
+ /**
+ * Add join metadata for a persistent entity.
+ *
+ * @param persistentClass The persistent entity metadata.
+ * @param joins The join metadata to add.
+ *
+ * @throws MappingException
+ */
+ public void addJoins(PersistentClass persistentClass, Map<String, Join> joins);
+
+ /**
+ * Get and maintain a cache of class type.
+ *
+ * @param clazz The XClass mapping
+ *
+ * @return The class type.
+ */
+ public AnnotatedClassType getClassType(XClass clazz);
+
+ /**
+ * FIXME should be private but will this break things?
+ * Add a class type.
+ *
+ * @param clazz The XClass mapping.
+ *
+ * @return The class type.
+ */
+ public AnnotatedClassType addClassType(XClass clazz);
+
+ /**
+ * @deprecated Use {@link #getUniqueConstraintHoldersByTable} instead
+ */
+ @SuppressWarnings({ "JavaDoc" })
+ public Map<Table, List<String[]>> getTableUniqueConstraints();
+
+ public Map<Table, List<UniqueConstraintHolder>>
getUniqueConstraintHoldersByTable();
+
+ /**
+ * @deprecated Use {@link #addUniqueConstraintHolders} instead
+ */
+ @SuppressWarnings({ "JavaDoc" })
+ public void addUniqueConstraints(Table table, List uniqueConstraints);
+
+ public void addUniqueConstraintHolders(Table table, List<UniqueConstraintHolder>
uniqueConstraintHolders);
+
+ public void addMappedBy(String entityName, String propertyName, String
inversePropertyName);
+
+ public String getFromMappedBy(String entityName, String propertyName);
+
+ public void addPropertyReferencedAssociation(String entityName, String propertyName,
String propertyRef);
+
+ public String getPropertyReferencedAssociation(String entityName, String propertyName);
+
+ public ReflectionManager getReflectionManager();
+
+ public void addDefaultQuery(String name, NamedQueryDefinition query);
+
+ public void addDefaultSQLQuery(String name, NamedSQLQueryDefinition query);
+
+ public void addDefaultResultSetMapping(ResultSetMappingDefinition definition);
+
+ public Map getClasses();
+
+ public void addAnyMetaDef(AnyMetaDef defAnn) throws AnnotationException;
+
+ public AnyMetaDef getAnyMetaDef(String name);
+
+ public boolean isInSecondPass();
+
+ /**
+ * Return the property annotated with @MapsId("propertyName") if any.
+ * Null otherwise
+ */
+ public PropertyData getPropertyAnnotatedWithMapsId(XClass entityType, String
propertyName);
+
+ public void addPropertyAnnotatedWithMapsId(XClass entityType, PropertyData property);
+
+ /**
+ * Should we use the new generator strategy mappings. This is controlled by the
+ * {@link AnnotationConfiguration#USE_NEW_ID_GENERATOR_MAPPINGS} setting.
+ *
+ * @return True if the new generators should be used, false otherwise.
+ */
+ public boolean useNewGeneratorMappings();
+
+ /**
+ * Return the property annotated with @ToOne and @Id if any.
+ * Null otherwise
+ */
+ public PropertyData getPropertyAnnotatedWithIdAndToOne(XClass entityType, String
propertyName);
+
+ void addToOneAndIdProperty(XClass entity, PropertyData property);
+
+ /**
+ * @param fetchProfile The fetch profile to test.
+ * @return {@code true} if the provided fetch profile has been configured via
annotations, {@code false} otherwise.
+ */
+ boolean isAnnotationConfiguredFetchProfile(FetchProfile fetchProfile);
+}
\ No newline at end of file
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/ExtendedMappings.java
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/FkSecondPass.java (from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/FkSecondPass.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/FkSecondPass.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/FkSecondPass.java 2010-07-08 23:41:23
UTC (rev 19921)
@@ -0,0 +1,78 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.hibernate.mapping.SimpleValue;
+import org.hibernate.mapping.Value;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public abstract class FkSecondPass implements SecondPass {
+ protected SimpleValue value;
+ protected Ejb3JoinColumn[] columns;
+ /**
+ * unique counter is needed to differentiate 2 instances of FKSecondPass
+ * as they are compared.
+ * Fairly hacky but IBM VM sometimes returns the same hashCode for 2 different objects
+ * TODO is it doable to rely on the Ejb3JoinColumn names? Not sure at they could be
inferred
+ */
+ private int uniqueCounter;
+ private static AtomicInteger globalCounter = new AtomicInteger();
+
+ public FkSecondPass(SimpleValue value, Ejb3JoinColumn[] columns) {
+ this.value = value;
+ this.columns = columns;
+ this.uniqueCounter = globalCounter.getAndIncrement();
+ }
+
+ public int getUniqueCounter() {
+ return uniqueCounter;
+ }
+
+ public Value getValue() {
+ return value;
+ }
+
+ public boolean equals(Object o) {
+ if ( this == o ) return true;
+ if ( !( o instanceof FkSecondPass ) ) return false;
+
+ FkSecondPass that = (FkSecondPass) o;
+
+ if ( uniqueCounter != that.uniqueCounter ) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ return uniqueCounter;
+ }
+
+ public abstract String getReferencedEntityName();
+
+ public abstract boolean isInPrimaryKey();
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/cfg/FkSecondPass.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/IndexColumn.java (from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/IndexColumn.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/IndexColumn.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/IndexColumn.java 2010-07-08 23:41:23
UTC (rev 19921)
@@ -0,0 +1,147 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.util.Map;
+
+import javax.persistence.OrderColumn;
+
+import org.hibernate.mapping.Join;
+
+/**
+ * index column
+ *
+ * @author inger
+ */
+public class IndexColumn
+ extends Ejb3Column {
+
+ private int base;
+
+ //FIXME move to a getter setter strategy for readeability
+ public IndexColumn(
+ boolean isImplicit,
+ String sqlType,
+ int length,
+ int precision,
+ int scale,
+ String name,
+ boolean nullable,
+ boolean unique,
+ boolean insertable,
+ boolean updatable,
+ String secondaryTableName,
+ Map<String, Join> joins,
+ PropertyHolder propertyHolder,
+ ExtendedMappings mappings
+ ) {
+ super();
+ setImplicit( isImplicit );
+ setSqlType( sqlType );
+ setLength( length );
+ setPrecision( precision );
+ setScale( scale );
+ setLogicalColumnName( name );
+ setNullable( nullable );
+ setUnique( unique );
+ setInsertable( insertable );
+ setUpdatable( updatable );
+ setSecondaryTableName( secondaryTableName );
+ setPropertyHolder( propertyHolder );
+ setJoins( joins );
+ setMappings( mappings );
+ bind();
+ //super(isImplicit, sqlType, length, precision, scale, name, nullable, unique,
insertable, updatable, secondaryTableName, joins, propertyHolder, mappings);
+
+ }
+
+ public int getBase() {
+ return base;
+ }
+
+ public void setBase(int base) {
+ this.base = base;
+ }
+
+ //JPA 2 @OrderColumn processing
+ public static IndexColumn buildColumnFromAnnotation(
+ OrderColumn ann,
+ PropertyHolder propertyHolder,
+ PropertyData inferredData,
+ Map<String, Join> secondaryTables,
+ ExtendedMappings mappings
+ ) {
+ IndexColumn column;
+ if ( ann != null ) {
+ String sqlType = BinderHelper.isDefault( ann.columnDefinition() ) ? null :
ann.columnDefinition();
+ String name = BinderHelper.isDefault( ann.name() ) ? inferredData.getPropertyName() +
"_ORDER" : ann.name();
+ //TODO move it to a getter based system and remove the constructor
+// The JPA OrderColumn annotation defines no table element...
+// column = new IndexColumn(
+// false, sqlType, 0, 0, 0, name, ann.nullable(),
+// false, ann.insertable(), ann.updatable(), ann.table(),
+// secondaryTables, propertyHolder, mappings
+// );
+ column = new IndexColumn(
+ false, sqlType, 0, 0, 0, name, ann.nullable(),
+ false, ann.insertable(), ann.updatable(), /*ann.table()*/null,
+ secondaryTables, propertyHolder, mappings
+ );
+ }
+ else {
+ column = new IndexColumn(
+ true, null, 0, 0, 0, null, true,
+ false, true, true, null, null, propertyHolder, mappings
+ );
+ }
+ return column;
+ }
+
+ //legacy @IndexColumn processing
+ public static IndexColumn buildColumnFromAnnotation(
+ org.hibernate.annotations.IndexColumn ann,
+ PropertyHolder propertyHolder,
+ PropertyData inferredData,
+ ExtendedMappings mappings
+ ) {
+ IndexColumn column;
+ if ( ann != null ) {
+ String sqlType = BinderHelper.isDefault( ann.columnDefinition() ) ? null :
ann.columnDefinition();
+ String name = BinderHelper.isDefault( ann.name() ) ? inferredData.getPropertyName() :
ann.name();
+ //TODO move it to a getter based system and remove the constructor
+ column = new IndexColumn(
+ false, sqlType, 0, 0, 0, name, ann.nullable(),
+ false, true, true, null, null, propertyHolder, mappings
+ );
+ column.setBase( ann.base() );
+ }
+ else {
+ column = new IndexColumn(
+ true, null, 0, 0, 0, null, true,
+ false, true, true, null, null, propertyHolder, mappings
+ );
+ }
+ return column;
+ }
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/cfg/IndexColumn.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/IndexOrUniqueKeySecondPass.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/IndexOrUniqueKeySecondPass.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/IndexOrUniqueKeySecondPass.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/IndexOrUniqueKeySecondPass.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,103 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.util.Map;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.MappingException;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.Table;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class IndexOrUniqueKeySecondPass implements SecondPass {
+ private Table table;
+ private final String indexName;
+ private final String[] columns;
+ private final ExtendedMappings mappings;
+ private final Ejb3Column column;
+ private final boolean unique;
+
+ /**
+ * Build an index
+ */
+ public IndexOrUniqueKeySecondPass(Table table, String indexName, String[] columns,
ExtendedMappings mappings) {
+ this.table = table;
+ this.indexName = indexName;
+ this.columns = columns;
+ this.mappings = mappings;
+ this.column = null;
+ this.unique = false;
+ }
+
+ /**
+ * Build an index
+ */
+ public IndexOrUniqueKeySecondPass(String indexName, Ejb3Column column, ExtendedMappings
mappings) {
+ this( indexName, column, mappings, false );
+ }
+
+ /**
+ * Build an index if unique is false or a Unique Key if unique is true
+ */
+ public IndexOrUniqueKeySecondPass(String indexName, Ejb3Column column,
+ ExtendedMappings mappings, boolean unique) {
+ this.indexName = indexName;
+ this.column = column;
+ this.columns = null;
+ this.mappings = mappings;
+ this.unique = unique;
+ }
+
+ public void doSecondPass(Map persistentClasses) throws MappingException {
+ if ( columns != null ) {
+ for (String columnName : columns) {
+ addConstraintToColumn( columnName );
+ }
+ }
+ if ( column != null ) {
+ this.table = column.getTable();
+ addConstraintToColumn( mappings.getLogicalColumnName(
column.getMappingColumn().getQuotedName(), table ) );
+ }
+ }
+
+ private void addConstraintToColumn(String columnName) {
+ Column column = table.getColumn(
+ new Column(
+ mappings.getPhysicalColumnName( columnName, table )
+ )
+ );
+ if ( column == null ) {
+ throw new AnnotationException(
+ "@Index references a unknown column: " + columnName
+ );
+ }
+ if ( unique )
+ table.getOrCreateUniqueKey( indexName ).addColumn( column );
+ else
+ table.getOrCreateIndex( indexName ).addColumn( column );
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/IndexOrUniqueKeySecondPass.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/InheritanceState.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/cfg/InheritanceState.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/InheritanceState.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/InheritanceState.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,338 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.MappedSuperclass;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.annotations.common.reflection.XAnnotatedElement;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.cfg.annotations.EntityBinder;
+import org.hibernate.mapping.PersistentClass;
+
+/**
+ * Some extra data to the inheritance position of a class.
+ *
+ * @author Emmanuel Bernard
+ */
+public class InheritanceState {
+ private XClass clazz;
+
+ /**
+ * Has sibling (either mappedsuperclass entity)
+ */
+ private boolean hasSiblings = false;
+
+ /**
+ * a mother entity is available
+ */
+ private boolean hasParents = false;
+ private InheritanceType type;
+ private boolean isEmbeddableSuperclass = false;
+ private Map<XClass, InheritanceState> inheritanceStatePerClass;
+ private List<XClass> classesToProcessForMappedSuperclass = new
ArrayList<XClass>();
+ private ExtendedMappings mappings;
+ private AccessType accessType;
+ private ElementsToProcess elementsToProcess;
+ private Boolean hasIdClassOrEmbeddedId;
+
+ public InheritanceState(XClass clazz,
+ Map<XClass, InheritanceState> inheritanceStatePerClass,
+ ExtendedMappings mappings) {
+ this.setClazz( clazz );
+ this.mappings = mappings;
+ this.inheritanceStatePerClass = inheritanceStatePerClass;
+ extractInheritanceType();
+ }
+
+ private void extractInheritanceType() {
+ XAnnotatedElement element = getClazz();
+ Inheritance inhAnn = element.getAnnotation( Inheritance.class );
+ MappedSuperclass mappedSuperClass = element.getAnnotation( MappedSuperclass.class );
+ if ( mappedSuperClass != null ) {
+ setEmbeddableSuperclass( true );
+ setType( inhAnn == null ? null : inhAnn.strategy() );
+ }
+ else {
+ setType( inhAnn == null ? InheritanceType.SINGLE_TABLE : inhAnn.strategy() );
+ }
+ }
+
+ boolean hasTable() {
+ return !hasParents() || !InheritanceType.SINGLE_TABLE.equals( getType() );
+ }
+
+ boolean hasDenormalizedTable() {
+ return hasParents() && InheritanceType.TABLE_PER_CLASS.equals( getType() );
+ }
+
+ public static InheritanceState getInheritanceStateOfSuperEntity(
+ XClass clazz, Map<XClass, InheritanceState> states
+ ) {
+ XClass superclass = clazz;
+ do {
+ superclass = superclass.getSuperclass();
+ InheritanceState currentState = states.get( superclass );
+ if ( currentState != null && !currentState.isEmbeddableSuperclass() ) {
+ return currentState;
+ }
+ }
+ while ( superclass != null && !Object.class.getName().equals(
superclass.getName() ) );
+ return null;
+ }
+
+ public static InheritanceState getSuperclassInheritanceState(XClass clazz,
Map<XClass, InheritanceState> states) {
+ XClass superclass = clazz;
+ do {
+ superclass = superclass.getSuperclass();
+ InheritanceState currentState = states.get( superclass );
+ if ( currentState != null ) {
+ return currentState;
+ }
+ }
+ while ( superclass != null && !Object.class.getName().equals(
superclass.getName() ) );
+ return null;
+ }
+
+ public XClass getClazz() {
+ return clazz;
+ }
+
+ public void setClazz(XClass clazz) {
+ this.clazz = clazz;
+ }
+
+ public boolean hasSiblings() {
+ return hasSiblings;
+ }
+
+ public void setHasSiblings(boolean hasSiblings) {
+ this.hasSiblings = hasSiblings;
+ }
+
+ public boolean hasParents() {
+ return hasParents;
+ }
+
+ public void setHasParents(boolean hasParents) {
+ this.hasParents = hasParents;
+ }
+
+ public InheritanceType getType() {
+ return type;
+ }
+
+ public void setType(InheritanceType type) {
+ this.type = type;
+ }
+
+ public boolean isEmbeddableSuperclass() {
+ return isEmbeddableSuperclass;
+ }
+
+ public void setEmbeddableSuperclass(boolean embeddableSuperclass) {
+ isEmbeddableSuperclass = embeddableSuperclass;
+ }
+
+ void postProcess(PersistentClass persistenceClass, EntityBinder entityBinder) {
+ //make sure we run elements to process
+ getElementsToProcess();
+ addMappedSuperClassInMetadata( persistenceClass );
+ entityBinder.setPropertyAccessType( accessType );
+ }
+
+ public XClass getClassWithIdClass(boolean evenIfSubclass) {
+ if ( !evenIfSubclass && hasParents() ) {
+ return null;
+ }
+ if ( clazz.isAnnotationPresent( IdClass.class ) ) {
+ return clazz;
+ }
+ else {
+ InheritanceState state = InheritanceState.getSuperclassInheritanceState( clazz,
inheritanceStatePerClass );
+ if ( state != null ) {
+ return state.getClassWithIdClass( true );
+ }
+ else {
+ return null;
+ }
+ }
+ }
+
+ public Boolean hasIdClassOrEmbeddedId() {
+ if ( hasIdClassOrEmbeddedId == null ) {
+ hasIdClassOrEmbeddedId = false;
+ if ( getClassWithIdClass( true ) != null ) {
+ hasIdClassOrEmbeddedId = true;
+ }
+ else {
+ final ElementsToProcess process = getElementsToProcess();
+ for ( PropertyData property : process.getElements() ) {
+ if ( property.getProperty().isAnnotationPresent( EmbeddedId.class ) ) {
+ hasIdClassOrEmbeddedId = true;
+ break;
+ }
+ }
+ }
+ }
+ return hasIdClassOrEmbeddedId;
+ }
+
+ /*
+ * Get the annotated elements, guessing the access type from @Id or @EmbeddedId
presence.
+ * Change EntityBinder by side effect
+ */
+
+ public ElementsToProcess getElementsToProcess() {
+ if ( elementsToProcess == null ) {
+ InheritanceState inheritanceState = inheritanceStatePerClass.get( clazz );
+ assert !inheritanceState.isEmbeddableSuperclass();
+
+
+ getMappedSuperclassesTillNextEntityOrdered();
+
+ accessType = determineDefaultAccessType();
+
+ List<PropertyData> elements = new ArrayList<PropertyData>();
+ int deep = classesToProcessForMappedSuperclass.size();
+ int idPropertyCount = 0;
+
+ for ( int index = 0; index < deep; index++ ) {
+ PropertyContainer propertyContainer = new PropertyContainer(
+ classesToProcessForMappedSuperclass.get(
+ index
+ ), clazz
+ );
+ int currentIdPropertyCount = AnnotationBinder.addElementsOfClass(
+ elements, accessType, propertyContainer, mappings
+ );
+ idPropertyCount += currentIdPropertyCount;
+ }
+
+ if ( idPropertyCount == 0 && !inheritanceState.hasParents() ) {
+ throw new AnnotationException( "No identifier specified for entity: " +
clazz.getName() );
+ }
+ elementsToProcess = new ElementsToProcess( elements, idPropertyCount );
+ }
+ return elementsToProcess;
+ }
+
+ private AccessType determineDefaultAccessType() {
+ XClass xclass = clazz;
+ while ( xclass != null && !Object.class.getName().equals( xclass.getName() ) )
{
+ if ( xclass.isAnnotationPresent( Entity.class ) || xclass.isAnnotationPresent(
MappedSuperclass.class ) ) {
+ for ( XProperty prop : xclass.getDeclaredProperties( AccessType.PROPERTY.getType() )
) {
+ final boolean isEmbeddedId = prop.isAnnotationPresent( EmbeddedId.class );
+ if ( prop.isAnnotationPresent( Id.class ) || isEmbeddedId ) {
+ return AccessType.PROPERTY;
+ }
+ }
+ for ( XProperty prop : xclass.getDeclaredProperties( AccessType.FIELD.getType() ) )
{
+ final boolean isEmbeddedId = prop.isAnnotationPresent( EmbeddedId.class );
+ if ( prop.isAnnotationPresent( Id.class ) || isEmbeddedId ) {
+ return AccessType.FIELD;
+ }
+ }
+ }
+ xclass = xclass.getSuperclass();
+ }
+ throw new AnnotationException( "No identifier specified for entity: " + clazz
);
+ }
+
+ private void getMappedSuperclassesTillNextEntityOrdered() {
+
+ //ordered to allow proper messages on properties subclassing
+ XClass currentClassInHierarchy = clazz;
+ InheritanceState superclassState;
+ do {
+ classesToProcessForMappedSuperclass.add( 0, currentClassInHierarchy );
+ XClass superClass = currentClassInHierarchy;
+ do {
+ superClass = superClass.getSuperclass();
+ superclassState = inheritanceStatePerClass.get( superClass );
+ }
+ while ( superClass != null
+ && !mappings.getReflectionManager().equals( superClass, Object.class )
&& superclassState == null );
+
+ currentClassInHierarchy = superClass;
+ }
+ while ( superclassState != null && superclassState.isEmbeddableSuperclass() );
+ }
+
+ private void addMappedSuperClassInMetadata(PersistentClass persistentClass) {
+ //add @MappedSuperclass in the metadata
+ // classes from 0 to n-1 are @MappedSuperclass and should be linked
+ org.hibernate.mapping.MappedSuperclass mappedSuperclass = null;
+ final InheritanceState superEntityState =
+ InheritanceState.getInheritanceStateOfSuperEntity( clazz, inheritanceStatePerClass
);
+ PersistentClass superEntity =
+ superEntityState != null ?
+ mappings.getClass( superEntityState.getClazz().getName() ) :
+ null;
+ final int lastMappedSuperclass = classesToProcessForMappedSuperclass.size() - 1;
+ for ( int index = 0; index < lastMappedSuperclass; index++ ) {
+ org.hibernate.mapping.MappedSuperclass parentSuperclass = mappedSuperclass;
+ final Class<?> type = mappings.getReflectionManager()
+ .toClass( classesToProcessForMappedSuperclass.get( index ) );
+ //add MAppedSuperclass if not already there
+ mappedSuperclass = mappings.getMappedSuperclass( type );
+ if ( mappedSuperclass == null ) {
+ mappedSuperclass = new org.hibernate.mapping.MappedSuperclass( parentSuperclass,
superEntity );
+ mappedSuperclass.setMappedClass( type );
+ mappings.addMappedSuperclass( type, mappedSuperclass );
+ }
+ }
+ if ( mappedSuperclass != null ) {
+ persistentClass.setSuperMappedSuperclass( mappedSuperclass );
+ }
+ }
+
+ static final class ElementsToProcess {
+ private final List<PropertyData> properties;
+ private final int idPropertyCount;
+
+ public List<PropertyData> getElements() {
+ return properties;
+ }
+
+ public int getIdPropertyCount() {
+ return idPropertyCount;
+ }
+
+ private ElementsToProcess(List<PropertyData> properties, int idPropertyCount) {
+ this.properties = properties;
+ this.idPropertyCount = idPropertyCount;
+ }
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/InheritanceState.java
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/JoinedSubclassFkSecondPass.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/JoinedSubclassFkSecondPass.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/JoinedSubclassFkSecondPass.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/JoinedSubclassFkSecondPass.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,58 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.util.Map;
+
+import org.hibernate.MappingException;
+import org.hibernate.cfg.annotations.TableBinder;
+import org.hibernate.mapping.JoinedSubclass;
+import org.hibernate.mapping.SimpleValue;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@SuppressWarnings({"serial", "unchecked"})
+public class JoinedSubclassFkSecondPass extends FkSecondPass {
+ private JoinedSubclass entity;
+ private ExtendedMappings mappings;
+
+ public JoinedSubclassFkSecondPass(JoinedSubclass entity, Ejb3JoinColumn[]
inheritanceJoinedColumns, SimpleValue key, ExtendedMappings mappings) {
+ super( key, inheritanceJoinedColumns );
+ this.entity = entity;
+ this.mappings = mappings;
+ }
+
+ public String getReferencedEntityName() {
+ return entity.getSuperclass().getEntityName();
+ }
+
+ public boolean isInPrimaryKey() {
+ return true;
+ }
+
+ public void doSecondPass(Map persistentClasses) throws MappingException {
+ TableBinder.bindFk( entity.getSuperclass(), entity, columns, value, false, mappings );
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/JoinedSubclassFkSecondPass.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/NotYetImplementedException.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/NotYetImplementedException.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/NotYetImplementedException.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/NotYetImplementedException.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,47 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import org.hibernate.MappingException;
+
+/**
+ * Mapping not yet implemented
+ *
+ * @author Emmanuel Bernard
+ */
+public class NotYetImplementedException extends MappingException {
+
+ public NotYetImplementedException(String msg, Throwable root) {
+ super( msg, root );
+ }
+
+ public NotYetImplementedException(Throwable root) {
+ super( root );
+ }
+
+ public NotYetImplementedException(String s) {
+ super( s );
+ }
+
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/NotYetImplementedException.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,280 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.MappingException;
+import org.hibernate.annotations.ForeignKey;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.cfg.annotations.PropertyBinder;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.DependantValue;
+import org.hibernate.mapping.Join;
+import org.hibernate.mapping.ManyToOne;
+import org.hibernate.mapping.OneToOne;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.SimpleValue;
+import org.hibernate.type.ForeignKeyDirection;
+import org.hibernate.util.StringHelper;
+
+/**
+ * We have to handle OneToOne in a second pass because:
+ * -
+ */
+public class OneToOneSecondPass implements SecondPass {
+ private String mappedBy;
+ private ExtendedMappings mappings;
+ private String ownerEntity;
+ private String ownerProperty;
+ private PropertyHolder propertyHolder;
+ private boolean ignoreNotFound;
+ private PropertyData inferredData;
+ private XClass targetEntity;
+ private boolean cascadeOnDelete;
+ private boolean optional;
+ private String cascadeStrategy;
+ private Ejb3JoinColumn[] joinColumns;
+
+ //that suck, we should read that from the property mainly
+ public OneToOneSecondPass(
+ String mappedBy, String ownerEntity, String ownerProperty,
+ PropertyHolder propertyHolder, PropertyData inferredData, XClass targetEntity, boolean
ignoreNotFound,
+ boolean cascadeOnDelete, boolean optional, String cascadeStrategy, Ejb3JoinColumn[]
columns,
+ ExtendedMappings mappings
+ ) {
+ this.ownerEntity = ownerEntity;
+ this.ownerProperty = ownerProperty;
+ this.mappedBy = mappedBy;
+ this.propertyHolder = propertyHolder;
+ this.mappings = mappings;
+ this.ignoreNotFound = ignoreNotFound;
+ this.inferredData = inferredData;
+ this.targetEntity = targetEntity;
+ this.cascadeOnDelete = cascadeOnDelete;
+ this.optional = optional;
+ this.cascadeStrategy = cascadeStrategy;
+ this.joinColumns = columns;
+ }
+
+ //TODO refactor this code, there is a lot of duplication in this method
+ public void doSecondPass(Map persistentClasses) throws MappingException {
+ org.hibernate.mapping.OneToOne value = new org.hibernate.mapping.OneToOne(
+ mappings, propertyHolder.getTable(), propertyHolder.getPersistentClass()
+ );
+ final String propertyName = inferredData.getPropertyName();
+ value.setPropertyName( propertyName );
+ String referencedEntityName = ToOneBinder.getReferenceEntityName(inferredData,
targetEntity, mappings);
+ value.setReferencedEntityName( referencedEntityName );
+ AnnotationBinder.defineFetchingStrategy( value, inferredData.getProperty() );
+ //value.setFetchMode( fetchMode );
+ value.setCascadeDeleteEnabled( cascadeOnDelete );
+ //value.setLazy( fetchMode != FetchMode.JOIN );
+
+ if ( !optional ) value.setConstrained( true );
+ value.setForeignKeyType(
+ value.isConstrained() ?
+ ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT :
+ ForeignKeyDirection.FOREIGN_KEY_TO_PARENT
+ );
+ PropertyBinder binder = new PropertyBinder();
+ binder.setName( propertyName );
+ binder.setValue( value );
+ binder.setCascade( cascadeStrategy );
+ binder.setAccessType( inferredData.getDefaultAccess() );
+ Property prop = binder.makeProperty();
+ if ( BinderHelper.isDefault( mappedBy ) ) {
+ /*
+ * we need to check if the columns are in the right order
+ * if not, then we need to create a many to one and formula
+ * but actually, since entities linked by a one to one need
+ * to share the same composite id class, this cannot happen in hibernate
+ */
+ boolean rightOrder = true;
+
+ if ( rightOrder ) {
+ String path = StringHelper.qualify( propertyHolder.getPath(), propertyName );
+ ( new ToOneFkSecondPass(
+ value, joinColumns,
+ !optional, //cannot have nullabe and unique on certain DBs
+ propertyHolder.getEntityOwnerClassName(),
+ path, mappings
+ ) ).doSecondPass( persistentClasses );
+ //no column associated since its a one to one
+ propertyHolder.addProperty( prop, inferredData.getDeclaringClass() );
+ }
+ else {
+ //this is a many to one with Formula
+
+ }
+ }
+ else {
+ PersistentClass otherSide = (PersistentClass) persistentClasses.get(
value.getReferencedEntityName() );
+ Property otherSideProperty;
+ try {
+ if ( otherSide == null ) {
+ throw new MappingException( "Unable to find entity: " +
value.getReferencedEntityName() );
+ }
+ otherSideProperty = BinderHelper.findPropertyByName( otherSide, mappedBy );
+ }
+ catch (MappingException e) {
+ throw new AnnotationException(
+ "Unknown mappedBy in: " + StringHelper.qualify( ownerEntity,
ownerProperty )
+ + ", referenced property unknown: "
+ + StringHelper.qualify( value.getReferencedEntityName(), mappedBy )
+ );
+ }
+ if ( otherSideProperty == null ) {
+ throw new AnnotationException(
+ "Unknown mappedBy in: " + StringHelper.qualify( ownerEntity,
ownerProperty )
+ + ", referenced property unknown: "
+ + StringHelper.qualify( value.getReferencedEntityName(), mappedBy )
+ );
+ }
+ if ( otherSideProperty.getValue() instanceof OneToOne ) {
+ propertyHolder.addProperty( prop, inferredData.getDeclaringClass() );
+ }
+ else if ( otherSideProperty.getValue() instanceof ManyToOne ) {
+ Iterator it = otherSide.getJoinIterator();
+ Join otherSideJoin = null;
+ while ( it.hasNext() ) {
+ Join otherSideJoinValue = (Join) it.next();
+ if ( otherSideJoinValue.containsProperty( otherSideProperty ) ) {
+ otherSideJoin = otherSideJoinValue;
+ break;
+ }
+ }
+ if ( otherSideJoin != null ) {
+ //@OneToOne @JoinTable
+ Join mappedByJoin = buildJoinFromMappedBySide(
+ (PersistentClass) persistentClasses.get( ownerEntity ), otherSideProperty,
otherSideJoin
+ );
+ ManyToOne manyToOne = new ManyToOne( mappings, mappedByJoin.getTable() );
+ //FIXME use ignore not found here
+ manyToOne.setIgnoreNotFound( ignoreNotFound );
+ manyToOne.setCascadeDeleteEnabled( value.isCascadeDeleteEnabled() );
+ manyToOne.setEmbedded( value.isEmbedded() );
+ manyToOne.setFetchMode( value.getFetchMode() );
+ manyToOne.setLazy( value.isLazy() );
+ manyToOne.setReferencedEntityName( value.getReferencedEntityName() );
+ manyToOne.setUnwrapProxy( value.isUnwrapProxy() );
+ prop.setValue( manyToOne );
+ Iterator otherSideJoinKeyColumns = otherSideJoin.getKey().getColumnIterator();
+ while ( otherSideJoinKeyColumns.hasNext() ) {
+ Column column = (Column) otherSideJoinKeyColumns.next();
+ Column copy = new Column();
+ copy.setLength( column.getLength() );
+ copy.setScale( column.getScale() );
+ copy.setValue( manyToOne );
+ copy.setName( column.getQuotedName() );
+ copy.setNullable( column.isNullable() );
+ copy.setPrecision( column.getPrecision() );
+ copy.setUnique( column.isUnique() );
+ copy.setSqlType( column.getSqlType() );
+ copy.setCheckConstraint( column.getCheckConstraint() );
+ copy.setComment( column.getComment() );
+ copy.setDefaultValue( column.getDefaultValue() );
+ manyToOne.addColumn( copy );
+ }
+ mappedByJoin.addProperty( prop );
+ }
+ else {
+ propertyHolder.addProperty( prop, inferredData.getDeclaringClass() );
+ }
+
+ value.setReferencedPropertyName( mappedBy );
+
+ String propertyRef = value.getReferencedPropertyName();
+ if ( propertyRef != null ) {
+ mappings.addUniquePropertyReference(
+ value.getReferencedEntityName(),
+ propertyRef
+ );
+ }
+ }
+ else {
+ throw new AnnotationException(
+ "Referenced property not a (One|Many)ToOne: "
+ + StringHelper.qualify(
+ otherSide.getEntityName(), mappedBy
+ )
+ + " in mappedBy of "
+ + StringHelper.qualify( ownerEntity, ownerProperty )
+ );
+ }
+ }
+ ForeignKey fk = inferredData.getProperty().getAnnotation( ForeignKey.class );
+ String fkName = fk != null ? fk.name() : "";
+ if ( !BinderHelper.isDefault( fkName ) ) value.setForeignKeyName( fkName );
+ }
+
+ /**
+ * Builds the <code>Join</code> instance for the mapped by side of a
<i>OneToOne</i> association using
+ * a join tables.
+ * <p>
+ * Note:<br/>
+ * <ul>
+ * <li>From the mappedBy side we should not create the PK nor the FK, this is
handled from the other side.</li>
+ * <li>This method is a dirty dupe of EntityBinder.bindSecondaryTable</i>.
+ * </p>
+ */
+ private Join buildJoinFromMappedBySide(PersistentClass persistentClass, Property
otherSideProperty, Join originalJoin) {
+ Join join = new Join();
+ join.setPersistentClass( persistentClass );
+
+ //no check constraints available on joins
+ join.setTable( originalJoin.getTable() );
+ join.setInverse( true );
+ SimpleValue key = new DependantValue( mappings, join.getTable(),
persistentClass.getIdentifier() );
+ //TODO support @ForeignKey
+ join.setKey( key );
+ join.setSequentialSelect( false );
+ //TODO support for inverse and optional
+ join.setOptional( true ); //perhaps not quite per-spec, but a Good Thing anyway
+ key.setCascadeDeleteEnabled( false );
+ Iterator mappedByColumns = otherSideProperty.getValue().getColumnIterator();
+ while ( mappedByColumns.hasNext() ) {
+ Column column = (Column) mappedByColumns.next();
+ Column copy = new Column();
+ copy.setLength( column.getLength() );
+ copy.setScale( column.getScale() );
+ copy.setValue( key );
+ copy.setName( column.getQuotedName() );
+ copy.setNullable( column.isNullable() );
+ copy.setPrecision( column.getPrecision() );
+ copy.setUnique( column.isUnique() );
+ copy.setSqlType( column.getSqlType() );
+ copy.setCheckConstraint( column.getCheckConstraint() );
+ copy.setComment( column.getComment() );
+ copy.setDefaultValue( column.getDefaultValue() );
+ key.addColumn( copy );
+ }
+ persistentClass.addJoin( join );
+ return join;
+ }
+}
+
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied:
core/trunk/core/src/main/java/org/hibernate/cfg/PkDrivenByDefaultMapsIdSecondPass.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/PkDrivenByDefaultMapsIdSecondPass.java)
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/cfg/PkDrivenByDefaultMapsIdSecondPass.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/PkDrivenByDefaultMapsIdSecondPass.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,38 @@
+package org.hibernate.cfg;
+
+import java.util.Map;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.MappingException;
+import org.hibernate.cfg.annotations.TableBinder;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.SimpleValue;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class PkDrivenByDefaultMapsIdSecondPass implements SecondPass {
+ private final String referencedEntityName;
+ private final Ejb3JoinColumn[] columns;
+ private final SimpleValue value;
+
+ public PkDrivenByDefaultMapsIdSecondPass(String referencedEntityName, Ejb3JoinColumn[]
columns, SimpleValue value) {
+ this.referencedEntityName = referencedEntityName;
+ this.columns = columns;
+ this.value = value;
+ }
+
+ public void doSecondPass(Map persistentClasses) throws MappingException {
+ PersistentClass referencedEntity = (PersistentClass) persistentClasses.get(
referencedEntityName );
+ if ( referencedEntity == null ) {
+ throw new AnnotationException(
+ "Unknown entity name: " + referencedEntityName
+ );
+ };
+ TableBinder.linkJoinColumnWithValueOverridingNameIfImplicit(
+ referencedEntity,
+ referencedEntity.getKey().getColumnIterator(),
+ columns,
+ value);
+ }
+}
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/PropertyContainer.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyContainer.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/PropertyContainer.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/PropertyContainer.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,283 @@
+// $Id$
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import javax.persistence.Access;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Transient;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.MappingException;
+import org.hibernate.annotations.ManyToAny;
+import org.hibernate.annotations.Target;
+import org.hibernate.annotations.Type;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.util.StringHelper;
+
+/**
+ * A helper class to keep the {@code XProperty}s of a class ordered by access type.
+ *
+ * @author Hardy Ferentschik
+ */
+class PropertyContainer {
+
+ private static final Logger log = LoggerFactory.getLogger( AnnotationBinder.class );
+
+ private final AccessType explicitClassDefinedAccessType;
+
+ /**
+ * Constains the properties which must be returned in case the class is accessed via
{@code AccessType.FIELD}. Note,
+ * this does not mean that all {@code XProperty}s in this map are fields. Due to JPA
access rules single properties
+ * can have different access type than the overall class access type.
+ */
+ private final TreeMap<String, XProperty> fieldAccessMap;
+
+ /**
+ * Constains the properties which must be returned in case the class is accessed via
{@code AccessType.Property}. Note,
+ * this does not mean that all {@code XProperty}s in this map are properties/methods.
Due to JPA access rules single properties
+ * can have different access type than the overall class access type.
+ */
+ private final TreeMap<String, XProperty> propertyAccessMap;
+
+ /**
+ * The class for which this container is created.
+ */
+ private final XClass xClass;
+ private final XClass entityAtStake;
+
+ PropertyContainer(XClass clazz, XClass entityAtStake) {
+ this.xClass = clazz;
+ this.entityAtStake = entityAtStake;
+
+ explicitClassDefinedAccessType = determineClassDefinedAccessStrategy();
+
+ // first add all properties to field and property map
+ fieldAccessMap = initProperties( AccessType.FIELD );
+ propertyAccessMap = initProperties( AccessType.PROPERTY );
+
+ considerExplicitFieldAndPropertyAccess();
+ }
+
+ public XClass getEntityAtStake() {
+ return entityAtStake;
+ }
+
+ public XClass getDeclaringClass() {
+ return xClass;
+ }
+
+ public AccessType getExplicitAccessStrategy() {
+ return explicitClassDefinedAccessType;
+ }
+
+ public boolean hasExplicitAccessStrategy() {
+ return !explicitClassDefinedAccessType.equals( AccessType.DEFAULT );
+ }
+
+ public Collection<XProperty> getProperties(AccessType accessType) {
+ assertTypesAreResolvable( accessType );
+ if ( AccessType.DEFAULT == accessType || AccessType.PROPERTY == accessType ) {
+ return Collections.unmodifiableCollection( propertyAccessMap.values() );
+ }
+ else {
+ return Collections.unmodifiableCollection( fieldAccessMap.values() );
+ }
+ }
+
+ private void assertTypesAreResolvable(AccessType access) {
+ Map<String, XProperty> xprops;
+ if ( AccessType.PROPERTY.equals( access ) || AccessType.DEFAULT.equals( access ) ) {
+ xprops = propertyAccessMap;
+ }
+ else {
+ xprops = fieldAccessMap;
+ }
+ for ( XProperty property : xprops.values() ) {
+ if ( !property.isTypeResolved() && !discoverTypeWithoutReflection( property )
) {
+ String msg = "Property " + StringHelper.qualify( xClass.getName(),
property.getName() ) +
+ " has an unbound type and no explicit target entity. Resolve this Generic
usage issue" +
+ " or set an explicit target attribute (eg @OneToMany(target=) or use an
explicit @Type";
+ throw new AnnotationException( msg );
+ }
+ }
+ }
+
+ private void considerExplicitFieldAndPropertyAccess() {
+ for ( XProperty property : fieldAccessMap.values() ) {
+ Access access = property.getAnnotation( Access.class );
+ if ( access == null ) {
+ continue;
+ }
+
+ // see "2.3.2 Explicit Access Type" of JPA 2 spec
+ // the access type for this property is explicitly set to AccessType.FIELD, hence we
have to
+ // use field access for this property even if the default access type for the class is
AccessType.PROPERTY
+ AccessType accessType = AccessType.getAccessStrategy( access.value() );
+ if ( accessType == AccessType.FIELD ) {
+ propertyAccessMap.put( property.getName(), property );
+ }
+ else { // AccessType.PROPERTY
+ log.warn( "Placing @Access(AccessType.PROPERTY) on a field does not have any
effect." );
+ }
+ }
+
+ for ( XProperty property : propertyAccessMap.values() ) {
+ Access access = property.getAnnotation( Access.class );
+ if ( access == null ) {
+ continue;
+ }
+
+ AccessType accessType = AccessType.getAccessStrategy( access.value() );
+
+ // see "2.3.2 Explicit Access Type" of JPA 2 spec
+ // the access type for this property is explicitly set to AccessType.PROPERTY, hence
we have to
+ // return use method access even if the default class access type is AccessType.FIELD
+ if ( accessType == AccessType.PROPERTY ) {
+ fieldAccessMap.put( property.getName(), property );
+ }
+ else { // AccessType.FIELD
+ log.warn( "Placing @Access(AccessType.FIELD) on a property does not have any
effect." );
+ }
+ }
+ }
+
+ /**
+ * Retrieves all properties from the {@code xClass} with the specified access type. This
method does not take
+ * any jpa access rules/annotations into account yet.
+ *
+ * @param access The access type - {@code AccessType.FIELD} or {@code
AccessType.Property}
+ *
+ * @return A maps of the properties with the given access type keyed against their
property name
+ */
+ private TreeMap<String, XProperty> initProperties(AccessType access) {
+ if ( !( AccessType.PROPERTY.equals( access ) || AccessType.FIELD.equals( access ) ) )
{
+ throw new IllegalArgumentException( "Acces type has to be AccessType.FIELD or
AccessType.Property" );
+ }
+
+ //order so that property are used in the same order when binding native query
+ TreeMap<String, XProperty> propertiesMap = new TreeMap<String,
XProperty>();
+ List<XProperty> properties = xClass.getDeclaredProperties( access.getType() );
+ for ( XProperty property : properties ) {
+ if ( mustBeSkipped( property ) ) {
+ continue;
+ }
+ propertiesMap.put( property.getName(), property );
+ }
+ return propertiesMap;
+ }
+
+ private AccessType determineClassDefinedAccessStrategy() {
+ AccessType classDefinedAccessType;
+
+ AccessType hibernateDefinedAccessType = AccessType.DEFAULT;
+ AccessType jpaDefinedAccessType = AccessType.DEFAULT;
+
+ org.hibernate.annotations.AccessType accessType = xClass.getAnnotation(
org.hibernate.annotations.AccessType.class );
+ if ( accessType != null ) {
+ hibernateDefinedAccessType = AccessType.getAccessStrategy( accessType.value() );
+ }
+
+ Access access = xClass.getAnnotation( Access.class );
+ if ( access != null ) {
+ jpaDefinedAccessType = AccessType.getAccessStrategy( access.value() );
+ }
+
+ if ( hibernateDefinedAccessType != AccessType.DEFAULT
+ && jpaDefinedAccessType != AccessType.DEFAULT
+ && hibernateDefinedAccessType != jpaDefinedAccessType ) {
+ throw new MappingException(
+ "@AccessType and @Access specified with contradicting values. Use of @Access
only is recommended. "
+ );
+ }
+
+ if ( hibernateDefinedAccessType != AccessType.DEFAULT ) {
+ classDefinedAccessType = hibernateDefinedAccessType;
+ }
+ else {
+ classDefinedAccessType = jpaDefinedAccessType;
+ }
+ return classDefinedAccessType;
+ }
+
+ private static boolean discoverTypeWithoutReflection(XProperty p) {
+ if ( p.isAnnotationPresent( OneToOne.class ) && !p.getAnnotation(
OneToOne.class )
+ .targetEntity()
+ .equals( void.class ) ) {
+ return true;
+ }
+ else if ( p.isAnnotationPresent( OneToMany.class ) && !p.getAnnotation(
OneToMany.class )
+ .targetEntity()
+ .equals( void.class ) ) {
+ return true;
+ }
+ else if ( p.isAnnotationPresent( ManyToOne.class ) && !p.getAnnotation(
ManyToOne.class )
+ .targetEntity()
+ .equals( void.class ) ) {
+ return true;
+ }
+ else if ( p.isAnnotationPresent( ManyToMany.class ) && !p.getAnnotation(
ManyToMany.class )
+ .targetEntity()
+ .equals( void.class ) ) {
+ return true;
+ }
+ else if ( p.isAnnotationPresent( org.hibernate.annotations.Any.class ) ) {
+ return true;
+ }
+ else if ( p.isAnnotationPresent( ManyToAny.class ) ) {
+ if ( !p.isCollection() && !p.isArray() ) {
+ throw new AnnotationException( "@ManyToAny used on a non collection non array
property: " + p.getName() );
+ }
+ return true;
+ }
+ else if ( p.isAnnotationPresent( Type.class ) ) {
+ return true;
+ }
+ else if ( p.isAnnotationPresent( Target.class ) ) {
+ return true;
+ }
+ return false;
+ }
+
+ private static boolean mustBeSkipped(XProperty property) {
+ //TODO make those hardcoded tests more portable (through the bytecode provider?)
+ return property.isAnnotationPresent( Transient.class )
+ || "net.sf.cglib.transform.impl.InterceptFieldCallback".equals(
property.getType().getName() )
+ || "org.hibernate.bytecode.javassist.FieldHandler".equals(
property.getType().getName() );
+ }
+}
+
+
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/PropertyContainer.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/PropertyData.java (from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyData.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/PropertyData.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/PropertyData.java 2010-07-08 23:41:23
UTC (rev 19921)
@@ -0,0 +1,75 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import org.hibernate.MappingException;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XProperty;
+
+public interface PropertyData {
+
+ /**
+ * @return default member access (whether field or property)
+ * @throws MappingException No getter or field found or wrong JavaBean spec usage
+ */
+ AccessType getDefaultAccess();
+
+ /**
+ * @return property name
+ * @throws MappingException No getter or field found or wrong JavaBean spec usage
+ */
+ String getPropertyName() throws MappingException;
+
+ /**
+ * Returns the returned class itself or the element type if an array
+ */
+ XClass getClassOrElement() throws MappingException;
+
+ /**
+ * Return the class itself
+ */
+ XClass getPropertyClass() throws MappingException;
+
+ /**
+ * Returns the returned class name itself or the element type if an array
+ */
+ String getClassOrElementName() throws MappingException;
+
+ /**
+ * Returns the returned class name itself
+ */
+ String getTypeName() throws MappingException;
+
+ /**
+ * Return the Hibernate mapping property
+ */
+ XProperty getProperty();
+
+ /**
+ * Return the Class the property is declared on
+ * If the property is declared on a @MappedSuperclass,
+ * this class will be different than the PersistentClass's class
+ */
+ XClass getDeclaringClass();
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/cfg/PropertyData.java
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/PropertyHolder.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyHolder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/PropertyHolder.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/PropertyHolder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,96 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import javax.persistence.Column;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+
+import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.mapping.Join;
+import org.hibernate.mapping.KeyValue;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.Table;
+import org.hibernate.annotations.common.reflection.XClass;
+
+/**
+ * Property holder abstract property containers from their direct implementation
+ *
+ * @author Emmanuel Bernard
+ */
+public interface PropertyHolder {
+ String getClassName();
+
+ String getEntityOwnerClassName();
+
+ Table getTable();
+
+ void addProperty(Property prop, XClass declaringClass);
+
+ void addProperty(Property prop, Ejb3Column[] columns, XClass declaringClass);
+
+ KeyValue getIdentifier();
+
+ /**
+ * Return true if this component is or is embedded in a @EmbeddedId
+ */
+ boolean isOrWithinEmbeddedId();
+
+ PersistentClass getPersistentClass();
+
+ boolean isComponent();
+
+ boolean isEntity();
+
+ void setParentProperty(String parentProperty);
+
+ String getPath();
+
+ /**
+ * return null if the column is not overridden, or an array of column if true
+ */
+ Column[] getOverriddenColumn(String propertyName);
+
+ /**
+ * return null if the column is not overridden, or an array of column if true
+ */
+ JoinColumn[] getOverriddenJoinColumn(String propertyName);
+
+ /**
+ * return
+ * - null if no join table is present,
+ * - the join table if not overridden,
+ * - the overridden join table otherwise
+ */
+ JoinTable getJoinTable(XProperty property);
+
+ String getEntityName();
+
+ Join addJoin(JoinTable joinTableAnn, boolean noDelayInPkColumnCreation);
+
+ boolean isInIdClass();
+
+ void setInIdClass(Boolean isInIdClass);
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/cfg/PropertyHolder.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/PropertyHolderBuilder.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyHolderBuilder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/PropertyHolderBuilder.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/PropertyHolderBuilder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,91 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.util.Map;
+
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.cfg.annotations.EntityBinder;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.Join;
+import org.hibernate.mapping.PersistentClass;
+
+/**
+ * This factory is here ot build a PropertyHolder and prevent .mapping interface adding
+ *
+ * @author Emmanuel Bernard
+ */
+public final class PropertyHolderBuilder {
+ private PropertyHolderBuilder() {
+ }
+
+ public static PropertyHolder buildPropertyHolder(
+ XClass clazzToProcess,
+ PersistentClass persistentClass,
+ EntityBinder entityBinder,
+ //Map<String, Join> joins,
+ ExtendedMappings mappings,
+ Map<XClass, InheritanceState> inheritanceStatePerClass
+ ) {
+ return new ClassPropertyHolder( persistentClass, clazzToProcess, entityBinder,
mappings, inheritanceStatePerClass );
+ }
+
+ /**
+ * build a component property holder
+ *
+ * @param component component to wrap
+ * @param path component path
+ * @param mappings
+ * @return PropertyHolder
+ */
+ public static PropertyHolder buildPropertyHolder(
+ Component component, String path, PropertyData inferredData, PropertyHolder parent,
+ ExtendedMappings mappings
+ ) {
+ return new ComponentPropertyHolder( component, path, inferredData, parent, mappings );
+ }
+
+ /**
+ * buid a property holder on top of a collection
+ */
+ public static PropertyHolder buildPropertyHolder(
+ Collection collection, String path, XClass clazzToProcess, XProperty property,
+ PropertyHolder parentPropertyHolder, ExtendedMappings mappings
+ ) {
+ return new CollectionPropertyHolder( collection, path, clazzToProcess, property,
parentPropertyHolder, mappings );
+ }
+
+ /**
+ * must only be used on second level phases (<join> has to be settled already)
+ */
+ public static PropertyHolder buildPropertyHolder(
+ PersistentClass persistentClass, Map<String, Join> joins,
+ ExtendedMappings mappings,
+ Map<XClass, InheritanceState> inheritanceStatePerClass
+ ) {
+ return new ClassPropertyHolder( persistentClass, null, joins, mappings,
inheritanceStatePerClass );
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/PropertyHolderBuilder.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/PropertyInferredData.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyInferredData.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/PropertyInferredData.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/PropertyInferredData.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,141 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import javax.persistence.Access;
+
+import org.hibernate.MappingException;
+import org.hibernate.annotations.Target;
+import org.hibernate.annotations.common.reflection.ReflectionManager;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XProperty;
+
+/**
+ * Retrieve all inferred data from an annnoted element
+ *
+ * @author Emmanuel Bernard
+ * @author Paolo Perrotta
+ */
+public class PropertyInferredData implements PropertyData {
+ private final AccessType defaultAccess;
+
+ private final XProperty property;
+ private final ReflectionManager reflectionManager;
+ private final XClass declaringClass;
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append( "PropertyInferredData" );
+ sb.append( "{property=" ).append( property );
+ sb.append( ", declaringClass=" ).append( declaringClass );
+ sb.append( '}' );
+ return sb.toString();
+ }
+
+ /**
+ * Take the annoted element for lazy process
+ */
+ public PropertyInferredData(XClass declaringClass, XProperty property, String
propertyAccessor, ReflectionManager reflectionManager) {
+ this.declaringClass = declaringClass;
+ this.property = property;
+ this.defaultAccess = AccessType.getAccessStrategy( propertyAccessor );
+ this.reflectionManager = reflectionManager;
+ }
+
+ public AccessType getDefaultAccess() throws MappingException {
+ AccessType accessType = defaultAccess;
+
+ AccessType hibernateAccessType = AccessType.DEFAULT;
+ AccessType jpaAccessType = AccessType.DEFAULT;
+
+ org.hibernate.annotations.AccessType accessTypeAnnotation = property.getAnnotation(
org.hibernate.annotations.AccessType.class );
+ if ( accessTypeAnnotation != null ) {
+ hibernateAccessType = AccessType.getAccessStrategy( accessTypeAnnotation.value() );
+ }
+
+ Access access = property.getAnnotation( Access.class );
+ if ( access != null ) {
+ jpaAccessType = AccessType.getAccessStrategy( access.value() );
+ }
+
+ if ( hibernateAccessType != AccessType.DEFAULT
+ && jpaAccessType != AccessType.DEFAULT
+ && hibernateAccessType != jpaAccessType ) {
+
+ StringBuilder builder = new StringBuilder();
+ builder.append( property.toString() );
+ builder.append(
+ " defines @AccessType and @Access with contradicting values. Use of @Access
only is recommended."
+ );
+ throw new MappingException( builder.toString() );
+ }
+
+ if ( hibernateAccessType != AccessType.DEFAULT ) {
+ accessType = hibernateAccessType;
+ }
+ else if ( jpaAccessType != AccessType.DEFAULT ) {
+ accessType = jpaAccessType;
+ }
+ return accessType;
+ }
+
+ public String getPropertyName() throws MappingException {
+ return property.getName();
+ }
+
+ public XClass getPropertyClass() throws MappingException {
+ if ( property.isAnnotationPresent( Target.class ) ) {
+ return reflectionManager.toXClass( property.getAnnotation( Target.class ).value() );
+ }
+ else {
+ return property.getType();
+ }
+ }
+
+ public XClass getClassOrElement() throws MappingException {
+ if ( property.isAnnotationPresent( Target.class ) ) {
+ return reflectionManager.toXClass( property.getAnnotation( Target.class ).value() );
+ }
+ else {
+ return property.getClassOrElementClass();
+ }
+ }
+
+ public String getClassOrElementName() throws MappingException {
+ return getClassOrElement().getName();
+ }
+
+ public String getTypeName() throws MappingException {
+ return getPropertyClass().getName();
+ }
+
+ public XProperty getProperty() {
+ return property;
+ }
+
+ public XClass getDeclaringClass() {
+ return declaringClass;
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/PropertyInferredData.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/PropertyPreloadedData.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyPreloadedData.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/PropertyPreloadedData.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/PropertyPreloadedData.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,76 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import org.hibernate.MappingException;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XProperty;
+
+public class PropertyPreloadedData implements PropertyData {
+ private final AccessType defaultAccess;
+
+ private final String propertyName;
+
+ private final XClass returnedClass;
+
+ public PropertyPreloadedData(AccessType defaultAccess, String propertyName, XClass
returnedClass) {
+ this.defaultAccess = defaultAccess;
+ this.propertyName = propertyName;
+ this.returnedClass = returnedClass;
+ }
+
+ public AccessType getDefaultAccess() throws MappingException {
+ return defaultAccess;
+ }
+
+ public String getPropertyName() throws MappingException {
+ return propertyName;
+ }
+
+ public XClass getClassOrElement() throws MappingException {
+ return getPropertyClass();
+ }
+
+ public XClass getPropertyClass() throws MappingException {
+ return returnedClass;
+ }
+
+ public String getClassOrElementName() throws MappingException {
+ return getTypeName();
+ }
+
+ public String getTypeName() throws MappingException {
+ return returnedClass == null ? null : returnedClass.getName();
+ }
+
+ public XProperty getProperty() {
+ return null; //instead of UnsupportedOperationException
+ }
+
+ public XClass getDeclaringClass() {
+ //Preloaded properties are artificial wrapper for colleciton element accesses
+ //and idClass creation, ignore.
+ return null;
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/PropertyPreloadedData.java
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/RecoverableException.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/RecoverableException.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/RecoverableException.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/RecoverableException.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,47 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import org.hibernate.AnnotationException;
+
+/**
+ * Should neven be exposed to the client
+ * An exception that wrap an underlying exception whith the hope
+ * subsequent processing will recover from it.
+ *
+ * @author Emmanuel Bernard
+ */
+public class RecoverableException extends AnnotationException {
+ public RecoverableException(String msg, Throwable root) {
+ super( msg, root );
+ }
+
+ public RecoverableException(Throwable root) {
+ super( root );
+ }
+
+ public RecoverableException(String s) {
+ super( s );
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/RecoverableException.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/SecondaryTableSecondPass.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/SecondaryTableSecondPass.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/SecondaryTableSecondPass.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/SecondaryTableSecondPass.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,50 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.util.Map;
+
+import org.hibernate.MappingException;
+import org.hibernate.annotations.common.reflection.XAnnotatedElement;
+import org.hibernate.cfg.annotations.EntityBinder;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class SecondaryTableSecondPass implements SecondPass {
+ private EntityBinder entityBinder;
+ private PropertyHolder propertyHolder;
+ private XAnnotatedElement annotatedClass;
+
+ public SecondaryTableSecondPass(EntityBinder entityBinder, PropertyHolder
propertyHolder, XAnnotatedElement annotatedClass) {
+ this.entityBinder = entityBinder;
+ this.propertyHolder = propertyHolder;
+ this.annotatedClass = annotatedClass;
+ }
+
+ public void doSecondPass(Map persistentClasses) throws MappingException {
+ entityBinder.finalSecondaryTableBinding( propertyHolder );
+
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/SecondaryTableSecondPass.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/SetSimpleValueTypeSecondPass.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/SetSimpleValueTypeSecondPass.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/SetSimpleValueTypeSecondPass.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/SetSimpleValueTypeSecondPass.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat, Inc. and/or its affiliates 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.util.Map;
+import org.hibernate.MappingException;
+import org.hibernate.cfg.annotations.SimpleValueBinder;
+
+/**
+ * @author Sharath Reddy
+ *
+ */
+public class SetSimpleValueTypeSecondPass implements SecondPass {
+
+ SimpleValueBinder binder;
+
+ public SetSimpleValueTypeSecondPass(SimpleValueBinder val) {
+ binder = val;
+ }
+
+ public void doSecondPass(Map persistentClasses) throws MappingException {
+ binder.fillSimpleValue();
+ }
+
+}
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/ToOneBinder.java (from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/ToOneBinder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/ToOneBinder.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/ToOneBinder.java 2010-07-08 23:41:23
UTC (rev 19921)
@@ -0,0 +1,53 @@
+package org.hibernate.cfg;
+
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToOne;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XProperty;
+
+/**
+ * Work in progress
+ * The goal of this class is to aggregate all operations
+ * related to ToOne binding operations
+ *
+ * @author Emmanuel Bernard
+ */
+public class ToOneBinder {
+ public static String getReferenceEntityName(PropertyData propertyData, XClass
targetEntity, ExtendedMappings mappings) {
+ if ( AnnotationBinder.isDefault( targetEntity, mappings ) ) {
+ return propertyData.getClassOrElementName();
+ }
+ else {
+ return targetEntity.getName();
+ }
+ }
+
+ public static String getReferenceEntityName(PropertyData propertyData, ExtendedMappings
mappings) {
+ XClass targetEntity = getTargetEntity( propertyData, mappings );
+ if ( AnnotationBinder.isDefault( targetEntity, mappings ) ) {
+ return propertyData.getClassOrElementName();
+ }
+ else {
+ return targetEntity.getName();
+ }
+ }
+
+ public static XClass getTargetEntity(PropertyData propertyData, ExtendedMappings
mappings) {
+ XProperty property = propertyData.getProperty();
+ return mappings.getReflectionManager().toXClass( getTargetEntityClass( property ) );
+ }
+
+ private static Class<?> getTargetEntityClass(XProperty property) {
+ final ManyToOne mTo = property.getAnnotation( ManyToOne.class );
+ if (mTo != null) {
+ return mTo.targetEntity();
+ }
+ final OneToOne oTo = property.getAnnotation( OneToOne.class );
+ if (oTo != null) {
+ return oTo.targetEntity();
+ }
+ throw new AssertionFailure("Unexpected discovery of a targetEntity: " +
property.getName() );
+ }
+}
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/ToOneFkSecondPass.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/cfg/ToOneFkSecondPass.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/ToOneFkSecondPass.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/ToOneFkSecondPass.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,124 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.util.Iterator;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.AssertionFailure;
+import org.hibernate.MappingException;
+import org.hibernate.cfg.annotations.TableBinder;
+import org.hibernate.mapping.ManyToOne;
+import org.hibernate.mapping.OneToOne;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.ToOne;
+import org.hibernate.mapping.KeyValue;
+import org.hibernate.mapping.Component;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Enable a proper set of the FK columns in respect with the id column order
+ * Allow the correct implementation of the default EJB3 values which needs both
+ * sides of the association to be resolved
+ *
+ * @author Emmanuel Bernard
+ */
+public class ToOneFkSecondPass extends FkSecondPass {
+ private boolean unique;
+ private ExtendedMappings mappings;
+ private String path;
+ private String entityClassName;
+
+ public ToOneFkSecondPass(
+ ToOne value, Ejb3JoinColumn[] columns, boolean unique, String entityClassName, String
path, ExtendedMappings mappings
+ ) {
+ super( value, columns );
+ this.mappings = mappings;
+ this.unique = unique;
+ this.entityClassName = entityClassName;
+ this.path = entityClassName != null ? path.substring( entityClassName.length() + 1 ) :
path;
+ }
+
+ public String getReferencedEntityName() {
+ return ( (ToOne) value ).getReferencedEntityName();
+ }
+
+ public boolean isInPrimaryKey() {
+ if ( entityClassName == null ) return false;
+ final PersistentClass persistentClass = mappings.getClass( entityClassName );
+ Property property = persistentClass.getIdentifierProperty();
+ if ( path == null ) {
+ return false;
+ }
+ else if ( property != null) {
+ //try explicit identifier property
+ return path.startsWith( property.getName() + "." );
+ }
+ else {
+ //try the embedded property
+ //embedded property starts their path with 'id.' See PropertyPreloadedData( )
use when idClass != null in AnnotationBinder
+ if ( path.startsWith( "id." ) ) {
+ KeyValue valueIdentifier = persistentClass.getIdentifier();
+ String localPath = path.substring( 3 );
+ if ( valueIdentifier instanceof Component ) {
+ Iterator it = ( (Component) valueIdentifier ).getPropertyIterator();
+ while ( it.hasNext() ) {
+ Property idProperty = (Property) it.next();
+ if ( localPath.startsWith( idProperty.getName() ) ) return true;
+ }
+
+ }
+ }
+ }
+ return false;
+ }
+
+ public void doSecondPass(java.util.Map persistentClasses) throws MappingException {
+ if ( value instanceof ManyToOne ) {
+ ManyToOne manyToOne = (ManyToOne) value;
+ PersistentClass ref = (PersistentClass) persistentClasses.get(
manyToOne.getReferencedEntityName() );
+ if ( ref == null ) {
+ throw new AnnotationException(
+ "@OneToOne or @ManyToOne on "
+ + StringHelper.qualify( entityClassName, path )
+ + " references an unknown entity: "
+ + manyToOne.getReferencedEntityName()
+ );
+ }
+ BinderHelper.createSyntheticPropertyReference( columns, ref, null, manyToOne, false,
mappings );
+ TableBinder.bindFk( ref, null, columns, manyToOne, unique, mappings );
+ /*
+ * HbmBinder does this only when property-ref != null, but IMO, it makes sense event
if it is null
+ */
+ if ( !manyToOne.isIgnoreNotFound() ) manyToOne.createPropertyRefConstraints(
persistentClasses );
+ }
+ else if ( value instanceof OneToOne ) {
+ ( (OneToOne) value ).createForeignKey();
+ }
+ else {
+ throw new AssertionFailure( "FkSecondPass for a wrong value type: " +
value.getClass().getName() );
+ }
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/ToOneFkSecondPass.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/UniqueConstraintHolder.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/UniqueConstraintHolder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/UniqueConstraintHolder.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/UniqueConstraintHolder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,55 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
+ * third-party contributors as indicated by either @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.cfg;
+
+/**
+ * {@link javax.persistence.UniqueConstraint} annotations are handled via second pass. I
do not
+ * understand the reasons why at this time, so here I use a holder object to hold the
information
+ * needed to create the unique constraint. The ability to name it is new, and so the
code used to
+ * simply keep this as a String array (the column names).
+ *
+ * @author Steve Ebersole
+ */
+public class UniqueConstraintHolder {
+ private String name;
+ private String[] columns;
+
+ public String getName() {
+ return name;
+ }
+
+ public UniqueConstraintHolder setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public String[] getColumns() {
+ return columns;
+ }
+
+ public UniqueConstraintHolder setColumns(String[] columns) {
+ this.columns = columns;
+ return this;
+ }
+}
Copied:
core/trunk/core/src/main/java/org/hibernate/cfg/VerifyFetchProfileReferenceSecondPass.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/VerifyFetchProfileReferenceSecondPass.java)
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/cfg/VerifyFetchProfileReferenceSecondPass.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/VerifyFetchProfileReferenceSecondPass.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,64 @@
+// $Id$
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import java.util.Map;
+
+import org.hibernate.MappingException;
+import org.hibernate.annotations.FetchProfile;
+import org.hibernate.mapping.PersistentClass;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class VerifyFetchProfileReferenceSecondPass implements SecondPass {
+
+ private String fetchProfileName;
+ private FetchProfile.FetchOverride fetch;
+ private ExtendedMappings mappings;
+
+ public VerifyFetchProfileReferenceSecondPass(String fetchProfileName,
FetchProfile.FetchOverride fetch, ExtendedMappings mappings) {
+ this.fetchProfileName = fetchProfileName;
+ this.fetch = fetch;
+ this.mappings = mappings;
+ }
+
+ public void doSecondPass(Map persistentClasses) throws MappingException {
+ org.hibernate.mapping.FetchProfile profile = mappings.findOrCreateFetchProfile(
fetchProfileName );
+ if ( !mappings.isAnnotationConfiguredFetchProfile( profile ) ) {
+ return;
+ }
+
+ PersistentClass clazz = mappings.getClass( fetch.entity().getName() );
+ // throws MappingException in case the property does not exist
+ clazz.getProperty( fetch.association() );
+
+ profile.addFetch(
+ fetch.entity().getName(), fetch.association(), fetch.mode().toString().toLowerCase()
+ );
+ }
+}
+
+
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/VerifyFetchProfileReferenceSecondPass.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/WrappedInferredData.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/cfg/WrappedInferredData.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/WrappedInferredData.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/WrappedInferredData.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,74 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg;
+
+import org.hibernate.MappingException;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.util.StringHelper;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class WrappedInferredData implements PropertyData {
+ private PropertyData wrappedInferredData;
+ private String propertyName;
+
+ public XClass getClassOrElement() throws MappingException {
+ return wrappedInferredData.getClassOrElement();
+ }
+
+ public String getClassOrElementName() throws MappingException {
+ return wrappedInferredData.getClassOrElementName();
+ }
+
+ public AccessType getDefaultAccess() {
+ return wrappedInferredData.getDefaultAccess();
+ }
+
+ public XProperty getProperty() {
+ return wrappedInferredData.getProperty();
+ }
+
+ public XClass getDeclaringClass() {
+ return wrappedInferredData.getDeclaringClass();
+ }
+
+ public XClass getPropertyClass() throws MappingException {
+ return wrappedInferredData.getPropertyClass();
+ }
+
+ public String getPropertyName() throws MappingException {
+ return propertyName;
+ }
+
+ public String getTypeName() throws MappingException {
+ return wrappedInferredData.getTypeName();
+ }
+
+ public WrappedInferredData(PropertyData inferredData, String suffix) {
+ this.wrappedInferredData = inferredData;
+ this.propertyName = StringHelper.qualify( inferredData.getPropertyName(), suffix );
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/WrappedInferredData.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/annotations/ArrayBinder.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/ArrayBinder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/annotations/ArrayBinder.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/ArrayBinder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,43 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg.annotations;
+
+import org.hibernate.mapping.Array;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.PersistentClass;
+
+/**
+ * Bind an Array
+ *
+ * @author Anthony Patricio
+ */
+public class ArrayBinder extends ListBinder {
+
+ public ArrayBinder() {
+ }
+
+ protected Collection createCollection(PersistentClass persistentClass) {
+ return new Array( getMappings(), persistentClass );
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/ArrayBinder.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/annotations/BagBinder.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/BagBinder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/annotations/BagBinder.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/annotations/BagBinder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,42 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg.annotations;
+
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.PersistentClass;
+
+/**
+ * Bind a bag.
+ *
+ * @author Matthew Inger
+ */
+public class BagBinder extends CollectionBinder {
+
+ public BagBinder() {
+ }
+
+ protected Collection createCollection(PersistentClass persistentClass) {
+ return new org.hibernate.mapping.Bag( getMappings(), persistentClass );
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/BagBinder.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,1533 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg.annotations;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import javax.persistence.AttributeOverride;
+import javax.persistence.AttributeOverrides;
+import javax.persistence.ElementCollection;
+import javax.persistence.Embeddable;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinColumns;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.MapKey;
+import javax.persistence.MapKeyColumn;
+import javax.persistence.OneToMany;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.FetchMode;
+import org.hibernate.MappingException;
+import org.hibernate.annotations.BatchSize;
+import org.hibernate.annotations.Cache;
+import org.hibernate.annotations.CollectionId;
+import org.hibernate.annotations.CollectionOfElements;
+import org.hibernate.annotations.Fetch;
+import org.hibernate.annotations.Filter;
+import org.hibernate.annotations.FilterJoinTable;
+import org.hibernate.annotations.FilterJoinTables;
+import org.hibernate.annotations.Filters;
+import org.hibernate.annotations.ForeignKey;
+import org.hibernate.annotations.Immutable;
+import org.hibernate.annotations.LazyCollection;
+import org.hibernate.annotations.LazyCollectionOption;
+import org.hibernate.annotations.Loader;
+import org.hibernate.annotations.ManyToAny;
+import org.hibernate.annotations.OptimisticLock;
+import org.hibernate.annotations.OrderBy;
+import org.hibernate.annotations.Persister;
+import org.hibernate.annotations.SQLDelete;
+import org.hibernate.annotations.SQLDeleteAll;
+import org.hibernate.annotations.SQLInsert;
+import org.hibernate.annotations.SQLUpdate;
+import org.hibernate.annotations.Sort;
+import org.hibernate.annotations.SortType;
+import org.hibernate.annotations.Where;
+import org.hibernate.annotations.WhereJoinTable;
+import org.hibernate.annotations.common.AssertionFailure;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.cfg.AccessType;
+import org.hibernate.cfg.AnnotatedClassType;
+import org.hibernate.cfg.AnnotationBinder;
+import org.hibernate.cfg.BinderHelper;
+import org.hibernate.cfg.CollectionSecondPass;
+import org.hibernate.cfg.Ejb3Column;
+import org.hibernate.cfg.Ejb3JoinColumn;
+import org.hibernate.cfg.ExtendedMappings;
+import org.hibernate.cfg.IndexColumn;
+import org.hibernate.cfg.InheritanceState;
+import org.hibernate.cfg.PropertyData;
+import org.hibernate.cfg.PropertyHolder;
+import org.hibernate.cfg.PropertyHolderBuilder;
+import org.hibernate.cfg.PropertyInferredData;
+import org.hibernate.cfg.PropertyPreloadedData;
+import org.hibernate.cfg.SecondPass;
+import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
+import org.hibernate.mapping.Any;
+import org.hibernate.mapping.Backref;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.DependantValue;
+import org.hibernate.mapping.IdGenerator;
+import org.hibernate.mapping.Join;
+import org.hibernate.mapping.KeyValue;
+import org.hibernate.mapping.ManyToOne;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.Selectable;
+import org.hibernate.mapping.SimpleValue;
+import org.hibernate.mapping.SingleTableSubclass;
+import org.hibernate.mapping.Table;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Base class for binding different types of collections to Hibernate configuration
objects.
+ *
+ * @author inger
+ * @author Emmanuel Bernard
+ */
+@SuppressWarnings({"unchecked", "serial"})
+public abstract class CollectionBinder {
+
+ private Logger log = LoggerFactory.getLogger( CollectionBinder.class );
+
+ protected Collection collection;
+ protected String propertyName;
+ PropertyHolder propertyHolder;
+ int batchSize;
+ private String mappedBy;
+ private XClass collectionType;
+ private XClass targetEntity;
+ private ExtendedMappings mappings;
+ private Ejb3JoinColumn[] inverseJoinColumns;
+ private String cascadeStrategy;
+ String cacheConcurrencyStrategy;
+ String cacheRegionName;
+ private boolean oneToMany;
+ protected IndexColumn indexColumn;
+ private String orderBy;
+ protected String hqlOrderBy;
+ private boolean isSorted;
+ private Class comparator;
+ private boolean hasToBeSorted;
+ protected boolean cascadeDeleteEnabled;
+ protected String mapKeyPropertyName;
+ private boolean insertable = true;
+ private boolean updatable = true;
+ private Ejb3JoinColumn[] fkJoinColumns;
+ private boolean isExplicitAssociationTable;
+ private Ejb3Column[] elementColumns;
+ private boolean isEmbedded;
+ private XProperty property;
+ private boolean ignoreNotFound;
+ private TableBinder tableBinder;
+ private Ejb3Column[] mapKeyColumns;
+ private Ejb3JoinColumn[] mapKeyManyToManyColumns;
+ protected HashMap<String, IdGenerator> localGenerators;
+ protected Map<XClass, InheritanceState> inheritanceStatePerClass;
+ private XClass declaringClass;
+ private boolean declaringClassSet;
+ private AccessType accessType;
+ private boolean hibernateExtensionMapping;
+
+ protected ExtendedMappings getMappings() {
+ return mappings;
+ }
+
+ public boolean isMap() {
+ return false;
+ }
+
+ public void setIsHibernateExtensionMapping(boolean hibernateExtensionMapping) {
+ this.hibernateExtensionMapping = hibernateExtensionMapping;
+ }
+
+ protected boolean isHibernateExtensionMapping() {
+ return hibernateExtensionMapping;
+ }
+
+ public void setUpdatable(boolean updatable) {
+ this.updatable = updatable;
+ }
+
+ public void setInheritanceStatePerClass(Map<XClass, InheritanceState>
inheritanceStatePerClass) {
+ this.inheritanceStatePerClass = inheritanceStatePerClass;
+ }
+
+ public void setInsertable(boolean insertable) {
+ this.insertable = insertable;
+ }
+
+ public void setCascadeStrategy(String cascadeStrategy) {
+ this.cascadeStrategy = cascadeStrategy;
+ }
+
+ public void setAccessType(AccessType accessType) {
+ this.accessType = accessType;
+ }
+
+ public void setInverseJoinColumns(Ejb3JoinColumn[] inverseJoinColumns) {
+ this.inverseJoinColumns = inverseJoinColumns;
+ }
+
+ public void setJoinColumns(Ejb3JoinColumn[] joinColumns) {
+ this.joinColumns = joinColumns;
+ }
+
+ private Ejb3JoinColumn[] joinColumns;
+
+ public void setPropertyHolder(PropertyHolder propertyHolder) {
+ this.propertyHolder = propertyHolder;
+ }
+
+ public void setBatchSize(BatchSize batchSize) {
+ this.batchSize = batchSize == null ? -1 : batchSize.size();
+ }
+
+ public void setEjb3OrderBy(javax.persistence.OrderBy orderByAnn) {
+ if ( orderByAnn != null ) {
+ hqlOrderBy = orderByAnn.value();
+ }
+ }
+
+ public void setSqlOrderBy(OrderBy orderByAnn) {
+ if ( orderByAnn != null ) {
+ if ( !BinderHelper.isDefault( orderByAnn.clause() ) ) {
+ orderBy = orderByAnn.clause();
+ }
+ }
+ }
+
+ public void setSort(Sort sortAnn) {
+ if ( sortAnn != null ) {
+ isSorted = !SortType.UNSORTED.equals( sortAnn.type() );
+ if ( isSorted && SortType.COMPARATOR.equals( sortAnn.type() ) ) {
+ comparator = sortAnn.comparator();
+ }
+ }
+ }
+
+ /**
+ * collection binder factory
+ */
+ public static CollectionBinder getCollectionBinder(
+ String entityName, XProperty property,
+ boolean isIndexed, boolean isHibernateExtensionMapping
+ ) {
+ CollectionBinder result;
+ if ( property.isArray() ) {
+ if ( property.getElementClass().isPrimitive() ) {
+ result = new PrimitiveArrayBinder();
+ }
+ else {
+ result = new ArrayBinder();
+ }
+ }
+ else if ( property.isCollection() ) {
+ //TODO consider using an XClass
+ Class returnedClass = property.getCollectionClass();
+ if ( java.util.Set.class.equals( returnedClass ) ) {
+ if ( property.isAnnotationPresent( CollectionId.class ) ) {
+ throw new AnnotationException( "Set do not support @CollectionId: "
+ + StringHelper.qualify( entityName, property.getName() ) );
+ }
+ result = new SetBinder();
+ }
+ else if ( java.util.SortedSet.class.equals( returnedClass ) ) {
+ if ( property.isAnnotationPresent( CollectionId.class ) ) {
+ throw new AnnotationException( "Set do not support @CollectionId: "
+ + StringHelper.qualify( entityName, property.getName() ) );
+ }
+ result = new SetBinder( true );
+ }
+ else if ( java.util.Map.class.equals( returnedClass ) ) {
+ if ( property.isAnnotationPresent( CollectionId.class ) ) {
+ throw new AnnotationException( "Map do not support @CollectionId: "
+ + StringHelper.qualify( entityName, property.getName() ) );
+ }
+ result = new MapBinder();
+ }
+ else if ( java.util.SortedMap.class.equals( returnedClass ) ) {
+ if ( property.isAnnotationPresent( CollectionId.class ) ) {
+ throw new AnnotationException( "Map do not support @CollectionId: "
+ + StringHelper.qualify( entityName, property.getName() ) );
+ }
+ result = new MapBinder( true );
+ }
+ else if ( java.util.Collection.class.equals( returnedClass ) ) {
+ if ( property.isAnnotationPresent( CollectionId.class ) ) {
+ result = new IdBagBinder();
+ }
+ else {
+ result = new BagBinder();
+ }
+ }
+ else if ( java.util.List.class.equals( returnedClass ) ) {
+ if ( isIndexed ) {
+ if ( property.isAnnotationPresent( CollectionId.class ) ) {
+ throw new AnnotationException(
+ "List do not support @CollectionId and @OrderColumn (or @IndexColumn) at the
same time: "
+ + StringHelper.qualify( entityName, property.getName() ) );
+ }
+ result = new ListBinder();
+ }
+ else if ( property.isAnnotationPresent( CollectionId.class ) ) {
+ result = new IdBagBinder();
+ }
+ else {
+ result = new BagBinder();
+ }
+ }
+ else {
+ throw new AnnotationException(
+ returnedClass.getName() + " collection not yet supported: "
+ + StringHelper.qualify( entityName, property.getName() )
+ );
+ }
+ }
+ else {
+ throw new AnnotationException(
+ "Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or
@CollectionOfElements: "
+ + StringHelper.qualify( entityName, property.getName() )
+ );
+ }
+ result.setIsHibernateExtensionMapping( isHibernateExtensionMapping );
+ return result;
+ }
+
+ protected CollectionBinder() {
+ }
+
+ protected CollectionBinder(boolean sorted) {
+ this.hasToBeSorted = sorted;
+ }
+
+ public void setMappedBy(String mappedBy) {
+ this.mappedBy = mappedBy;
+ }
+
+ public void setTableBinder(TableBinder tableBinder) {
+ this.tableBinder = tableBinder;
+ }
+
+ public void setCollectionType(XClass collectionType) {
+ this.collectionType = collectionType;
+ }
+
+ public void setTargetEntity(XClass targetEntity) {
+ this.targetEntity = targetEntity;
+ }
+
+ public void setMappings(ExtendedMappings mappings) {
+ this.mappings = mappings;
+ }
+
+ protected abstract Collection createCollection(PersistentClass persistentClass);
+
+ public Collection getCollection() {
+ return collection;
+ }
+
+ public void setPropertyName(String propertyName) {
+ this.propertyName = propertyName;
+ }
+
+ public void setDeclaringClass(XClass declaringClass) {
+ this.declaringClass = declaringClass;
+ this.declaringClassSet = true;
+ }
+
+ public void bind() {
+ this.collection = createCollection( propertyHolder.getPersistentClass() );
+ log.debug( "Collection role: {}", StringHelper.qualify(
propertyHolder.getPath(), propertyName ) );
+ collection.setRole( StringHelper.qualify( propertyHolder.getPath(), propertyName ) );
+ collection.setNodeName( propertyName );
+
+ if ( (property.isAnnotationPresent( org.hibernate.annotations.MapKey.class )
+ || property.isAnnotationPresent( MapKeyColumn.class ) )
+ && mapKeyPropertyName != null ) {
+ throw new AnnotationException(
+ "Cannot mix @javax.persistence.MapKey and @MapKeyColumn or
@org.hibernate.annotations.MapKey "
+ + "on the same collection: " + StringHelper.qualify(
+ propertyHolder.getPath(), propertyName
+ )
+ );
+ }
+
+ //set laziness
+ defineFetchingStrategy();
+ collection.setBatchSize( batchSize );
+ if ( orderBy != null && hqlOrderBy != null ) {
+ throw new AnnotationException(
+ "Cannot use sql order by clause in conjunction of EJB3 order by clause: "
+ safeCollectionRole()
+ );
+ }
+
+ collection.setMutable( !property.isAnnotationPresent( Immutable.class ) );
+ OptimisticLock lockAnn = property.getAnnotation( OptimisticLock.class );
+ if ( lockAnn != null ) collection.setOptimisticLocked( !lockAnn.excluded() );
+ Persister persisterAnn = property.getAnnotation( Persister.class );
+ if ( persisterAnn != null ) collection.setCollectionPersisterClass( persisterAnn.impl()
);
+
+ // set ordering
+ if ( orderBy != null ) collection.setOrderBy( orderBy );
+ if ( isSorted ) {
+ collection.setSorted( true );
+ if ( comparator != null ) {
+ try {
+ collection.setComparator( (Comparator) comparator.newInstance() );
+ }
+ catch (ClassCastException e) {
+ throw new AnnotationException(
+ "Comparator not implementing java.util.Comparator class: "
+ + comparator.getName() + "(" + safeCollectionRole() + ")"
+ );
+ }
+ catch (Exception e) {
+ throw new AnnotationException(
+ "Could not instantiate comparator class: "
+ + comparator.getName() + "(" + safeCollectionRole() + ")"
+ );
+ }
+ }
+ }
+ else {
+ if ( hasToBeSorted ) {
+ throw new AnnotationException(
+ "A sorted collection has to define @Sort: "
+ + safeCollectionRole()
+ );
+ }
+ }
+
+ //set cache
+ if ( StringHelper.isNotEmpty( cacheConcurrencyStrategy ) ) {
+ collection.setCacheConcurrencyStrategy( cacheConcurrencyStrategy );
+ collection.setCacheRegionName( cacheRegionName );
+ }
+
+ //SQL overriding
+ SQLInsert sqlInsert = property.getAnnotation( SQLInsert.class );
+ SQLUpdate sqlUpdate = property.getAnnotation( SQLUpdate.class );
+ SQLDelete sqlDelete = property.getAnnotation( SQLDelete.class );
+ SQLDeleteAll sqlDeleteAll = property.getAnnotation( SQLDeleteAll.class );
+ Loader loader = property.getAnnotation( Loader.class );
+ if ( sqlInsert != null ) {
+ collection.setCustomSQLInsert( sqlInsert.sql().trim(), sqlInsert.callable(),
+ ExecuteUpdateResultCheckStyle.parse( sqlInsert.check().toString().toLowerCase() )
+ );
+
+ }
+ if ( sqlUpdate != null ) {
+ collection.setCustomSQLUpdate( sqlUpdate.sql(), sqlUpdate.callable(),
+ ExecuteUpdateResultCheckStyle.parse( sqlUpdate.check().toString().toLowerCase() )
+ );
+ }
+ if ( sqlDelete != null ) {
+ collection.setCustomSQLDelete( sqlDelete.sql(), sqlDelete.callable(),
+ ExecuteUpdateResultCheckStyle.parse( sqlDelete.check().toString().toLowerCase() )
+ );
+ }
+ if ( sqlDeleteAll != null ) {
+ collection.setCustomSQLDeleteAll( sqlDeleteAll.sql(), sqlDeleteAll.callable(),
+ ExecuteUpdateResultCheckStyle.parse( sqlDeleteAll.check().toString().toLowerCase()
)
+ );
+ }
+ if ( loader != null ) {
+ collection.setLoaderName( loader.namedQuery() );
+ }
+
+ //work on association
+ boolean isMappedBy = !BinderHelper.isDefault( mappedBy );
+
+ if (isMappedBy
+ && (property.isAnnotationPresent( JoinColumn.class )
+ || property.isAnnotationPresent( JoinColumns.class )
+ || propertyHolder.getJoinTable( property ) != null ) ) {
+ String message = "Associations marked as mappedBy must not define database
mappings like @JoinTable or @JoinColumn: ";
+ message += StringHelper.qualify( propertyHolder.getPath(), propertyName );
+ throw new AnnotationException( message );
+ }
+
+ collection.setInverse( isMappedBy );
+
+ //many to many may need some second pass informations
+ if ( !oneToMany && isMappedBy ) {
+ mappings.addMappedBy( getCollectionType().getName(), mappedBy, propertyName );
+ }
+ //TODO reducce tableBinder != null and oneToMany
+ XClass collectionType = getCollectionType();
+ if ( inheritanceStatePerClass == null) throw new AssertionFailure(
"inheritanceStatePerClass not set" );
+ SecondPass sp = getSecondPass(
+ fkJoinColumns,
+ joinColumns,
+ inverseJoinColumns,
+ elementColumns,
+ mapKeyColumns, mapKeyManyToManyColumns, isEmbedded,
+ property, collectionType,
+ ignoreNotFound, oneToMany,
+ tableBinder, mappings
+ );
+ if ( collectionType.isAnnotationPresent( Embeddable.class )
+ || property.isAnnotationPresent( CollectionOfElements.class ) //legacy hibernate
+ || property.isAnnotationPresent( ElementCollection.class ) //JPA 2
+ ) {
+ // do it right away, otherwise @ManyToOne on composite element call addSecondPass
+ // and raise a ConcurrentModificationException
+ //sp.doSecondPass( CollectionHelper.EMPTY_MAP );
+ mappings.addSecondPass( sp, !isMappedBy );
+ }
+ else {
+ mappings.addSecondPass( sp, !isMappedBy );
+ }
+
+ mappings.addCollection( collection );
+
+ //property building
+ PropertyBinder binder = new PropertyBinder();
+ binder.setName( propertyName );
+ binder.setValue( collection );
+ binder.setCascade( cascadeStrategy );
+ if ( cascadeStrategy != null && cascadeStrategy.indexOf(
"delete-orphan" ) >= 0 ) {
+ collection.setOrphanDelete( true );
+ }
+ binder.setAccessType( accessType );
+ binder.setProperty( property );
+ binder.setInsertable( insertable );
+ binder.setUpdatable( updatable );
+ Property prop = binder.makeProperty();
+ //we don't care about the join stuffs because the column is on the association
table.
+ if (! declaringClassSet) throw new AssertionFailure( "DeclaringClass is not set in
CollectionBinder while binding" );
+ propertyHolder.addProperty( prop, declaringClass );
+ }
+
+ private void defineFetchingStrategy() {
+ LazyCollection lazy = property.getAnnotation( LazyCollection.class );
+ Fetch fetch = property.getAnnotation( Fetch.class );
+ OneToMany oneToMany = property.getAnnotation( OneToMany.class );
+ ManyToMany manyToMany = property.getAnnotation( ManyToMany.class );
+ CollectionOfElements collectionOfElements = property.getAnnotation(
CollectionOfElements.class ); //legacy hibernate
+ ElementCollection elementCollection = property.getAnnotation( ElementCollection.class
); //jpa 2
+ ManyToAny manyToAny = property.getAnnotation( ManyToAny.class );
+ FetchType fetchType;
+ if ( oneToMany != null ) {
+ fetchType = oneToMany.fetch();
+ }
+ else if ( manyToMany != null ) {
+ fetchType = manyToMany.fetch();
+ }
+ else if ( elementCollection != null ) {
+ fetchType = elementCollection.fetch();
+ }
+ else if ( collectionOfElements != null ) {
+ fetchType = collectionOfElements.fetch();
+ }
+ else if ( manyToAny != null ) {
+ fetchType = FetchType.LAZY;
+ }
+ else {
+ throw new AssertionFailure(
+ "Define fetch strategy on a property not annotated with @ManyToOne nor
@OneToMany nor @CollectionOfElements"
+ );
+ }
+ if ( lazy != null ) {
+ collection.setLazy( !( lazy.value() == LazyCollectionOption.FALSE ) );
+ collection.setExtraLazy( lazy.value() == LazyCollectionOption.EXTRA );
+ }
+ else {
+ collection.setLazy( fetchType == FetchType.LAZY );
+ collection.setExtraLazy( false );
+ }
+ if ( fetch != null ) {
+ if ( fetch.value() == org.hibernate.annotations.FetchMode.JOIN ) {
+ collection.setFetchMode( FetchMode.JOIN );
+ collection.setLazy( false );
+ }
+ else if ( fetch.value() == org.hibernate.annotations.FetchMode.SELECT ) {
+ collection.setFetchMode( FetchMode.SELECT );
+ }
+ else if ( fetch.value() == org.hibernate.annotations.FetchMode.SUBSELECT ) {
+ collection.setFetchMode( FetchMode.SELECT );
+ collection.setSubselectLoadable( true );
+ collection.getOwner().setSubselectLoadableCollections( true );
+ }
+ else {
+ throw new AssertionFailure( "Unknown FetchMode: " + fetch.value() );
+ }
+ }
+ else {
+ collection.setFetchMode( AnnotationBinder.getFetchMode( fetchType ) );
+ }
+ }
+
+ private XClass getCollectionType() {
+ if ( AnnotationBinder.isDefault( targetEntity, mappings ) ) {
+ if ( collectionType != null ) {
+ return collectionType;
+ }
+ else {
+ String errorMsg = "Collection has neither generic type or
OneToMany.targetEntity() defined: "
+ + safeCollectionRole();
+ throw new AnnotationException( errorMsg );
+ }
+ }
+ else {
+ return targetEntity;
+ }
+ }
+
+ public SecondPass getSecondPass(
+ final Ejb3JoinColumn[] fkJoinColumns, final Ejb3JoinColumn[] keyColumns,
+ final Ejb3JoinColumn[] inverseColumns,
+ final Ejb3Column[] elementColumns,
+ final Ejb3Column[] mapKeyColumns, final Ejb3JoinColumn[] mapKeyManyToManyColumns,
final boolean isEmbedded,
+ final XProperty property, final XClass collType,
+ final boolean ignoreNotFound, final boolean unique,
+ final TableBinder assocTableBinder, final ExtendedMappings mappings
+ ) {
+ return new CollectionSecondPass( mappings, collection ) {
+
+ public void secondPass(java.util.Map persistentClasses, java.util.Map inheritedMetas)
+ throws MappingException {
+ bindStarToManySecondPass(
+ persistentClasses, collType, fkJoinColumns, keyColumns, inverseColumns,
elementColumns,
+ isEmbedded, property, unique, assocTableBinder, ignoreNotFound, mappings
+ );
+
+ }
+ };
+ }
+
+ /**
+ * return true if it's a Fk, false if it's an association table
+ */
+ protected boolean bindStarToManySecondPass(
+ Map persistentClasses, XClass collType, Ejb3JoinColumn[] fkJoinColumns,
+ Ejb3JoinColumn[] keyColumns, Ejb3JoinColumn[] inverseColumns, Ejb3Column[]
elementColumns,
+ boolean isEmbedded,
+ XProperty property, boolean unique,
+ TableBinder associationTableBinder,
+ boolean ignoreNotFound, ExtendedMappings mappings
+ ) {
+ PersistentClass persistentClass = (PersistentClass) persistentClasses.get(
collType.getName() );
+ boolean reversePropertyInJoin = false;
+ if ( persistentClass != null && StringHelper.isNotEmpty( this.mappedBy ) ) {
+ try {
+ reversePropertyInJoin = 0 != persistentClass.getJoinNumber(
+ persistentClass.getRecursiveProperty( this.mappedBy )
+ );
+ }
+ catch (MappingException e) {
+ StringBuilder error = new StringBuilder( 80 );
+ error.append( "mappedBy reference an unknown target entity property: " )
+ .append( collType ).append( "." ).append( this.mappedBy )
+ .append( " in " )
+ .append( collection.getOwnerEntityName() )
+ .append( "." )
+ .append( property.getName() );
+ throw new AnnotationException( error.toString() );
+ }
+ }
+ if ( persistentClass != null
+ && !reversePropertyInJoin
+ && oneToMany
+ && !this.isExplicitAssociationTable
+ && ( joinColumns[0].isImplicit() && !BinderHelper.isDefault(
this.mappedBy ) //implicit @JoinColumn
+ || !fkJoinColumns[0].isImplicit() ) //this is an explicit @JoinColumn
+ ) {
+ //this is a Foreign key
+ bindOneToManySecondPass(
+ getCollection(),
+ persistentClasses,
+ fkJoinColumns,
+ collType,
+ cascadeDeleteEnabled,
+ ignoreNotFound, hqlOrderBy,
+ mappings,
+ inheritanceStatePerClass
+ );
+ return true;
+ }
+ else {
+ //this is an association table
+ bindManyToManySecondPass(
+ this.collection,
+ persistentClasses,
+ keyColumns,
+ inverseColumns,
+ elementColumns,
+ isEmbedded, collType,
+ ignoreNotFound, unique,
+ cascadeDeleteEnabled,
+ associationTableBinder, property, propertyHolder, hqlOrderBy, mappings
+ );
+ return false;
+ }
+ }
+
+ protected void bindOneToManySecondPass(
+ Collection collection, Map persistentClasses, Ejb3JoinColumn[] fkJoinColumns,
+ XClass collectionType,
+ boolean cascadeDeleteEnabled, boolean ignoreNotFound, String hqlOrderBy,
ExtendedMappings extendedMappings,
+ Map<XClass, InheritanceState> inheritanceStatePerClass
+ ) {
+
+ log.debug("Binding a OneToMany: {}.{} through a foreign key",
propertyHolder.getEntityName(), propertyName);
+ org.hibernate.mapping.OneToMany oneToMany = new org.hibernate.mapping.OneToMany(
extendedMappings, collection.getOwner() );
+ collection.setElement( oneToMany );
+ oneToMany.setReferencedEntityName( collectionType.getName() );
+ oneToMany.setIgnoreNotFound( ignoreNotFound );
+
+ String assocClass = oneToMany.getReferencedEntityName();
+ PersistentClass associatedClass = (PersistentClass) persistentClasses.get( assocClass
);
+ String orderBy = buildOrderByClauseFromHql( hqlOrderBy, associatedClass,
collection.getRole() );
+ if ( orderBy != null ) collection.setOrderBy( orderBy );
+ if ( mappings == null ) {
+ throw new AssertionFailure(
+ "CollectionSecondPass for oneToMany should not be called with null
mappings"
+ );
+ }
+ Map<String, Join> joins = mappings.getJoins( assocClass );
+ if ( associatedClass == null ) {
+ throw new MappingException(
+ "Association references unmapped class: " + assocClass
+ );
+ }
+ oneToMany.setAssociatedClass( associatedClass );
+ for (Ejb3JoinColumn column : fkJoinColumns) {
+ column.setPersistentClass( associatedClass, joins, inheritanceStatePerClass );
+ column.setJoins( joins );
+ collection.setCollectionTable( column.getTable() );
+ }
+ log.info(
+ "Mapping collection: " + collection.getRole() + " -> " +
collection.getCollectionTable().getName()
+ );
+ bindFilters( false );
+ bindCollectionSecondPass( collection, null, fkJoinColumns, cascadeDeleteEnabled,
property, mappings );
+ if ( !collection.isInverse()
+ && !collection.getKey().isNullable() ) {
+ // for non-inverse one-to-many, with a not-null fk, add a backref!
+ String entityName = oneToMany.getReferencedEntityName();
+ PersistentClass referenced = mappings.getClass( entityName );
+ Backref prop = new Backref();
+ prop.setName( '_' + fkJoinColumns[0].getPropertyName() + "Backref"
);
+ prop.setUpdateable( false );
+ prop.setSelectable( false );
+ prop.setCollectionRole( collection.getRole() );
+ prop.setEntityName( collection.getOwner().getEntityName() );
+ prop.setValue( collection.getKey() );
+ referenced.addProperty( prop );
+ }
+ }
+
+
+ private void bindFilters(boolean hasAssociationTable) {
+ Filter simpleFilter = property.getAnnotation( Filter.class );
+ //set filtering
+ //test incompatible choices
+ //if ( StringHelper.isNotEmpty( where ) ) collection.setWhere( where );
+ if ( simpleFilter != null ) {
+ if ( hasAssociationTable ) {
+ collection.addManyToManyFilter( simpleFilter.name(), getCondition( simpleFilter ) );
+ }
+ else {
+ collection.addFilter( simpleFilter.name(), getCondition( simpleFilter ) );
+ }
+ }
+ Filters filters = property.getAnnotation( Filters.class );
+ if ( filters != null ) {
+ for (Filter filter : filters.value()) {
+ if ( hasAssociationTable ) {
+ collection.addManyToManyFilter( filter.name(), getCondition( filter ) );
+ }
+ else {
+ collection.addFilter( filter.name(), getCondition( filter ) );
+ }
+ }
+ }
+ FilterJoinTable simpleFilterJoinTable = property.getAnnotation( FilterJoinTable.class
);
+ if ( simpleFilterJoinTable != null ) {
+ if ( hasAssociationTable ) {
+ collection.addFilter( simpleFilterJoinTable.name(), getCondition(
simpleFilterJoinTable ) );
+ }
+ else {
+ throw new AnnotationException(
+ "Illegal use of @FilterJoinTable on an association without join table:"
+ + StringHelper.qualify( propertyHolder.getPath(), propertyName )
+ );
+ }
+ }
+ FilterJoinTables filterJoinTables = property.getAnnotation( FilterJoinTables.class );
+ if ( filterJoinTables != null ) {
+ for (FilterJoinTable filter : filterJoinTables.value()) {
+ if ( hasAssociationTable ) {
+ collection.addFilter( filter.name(), getCondition( filter ) );
+ }
+ else {
+ throw new AnnotationException(
+ "Illegal use of @FilterJoinTable on an association without join table:"
+ + StringHelper.qualify( propertyHolder.getPath(), propertyName )
+ );
+ }
+ }
+ }
+
+ Where where = property.getAnnotation( Where.class );
+ String whereClause = where == null ? null : where.clause();
+ if ( StringHelper.isNotEmpty( whereClause ) ) {
+ if ( hasAssociationTable ) {
+ collection.setManyToManyWhere( whereClause );
+ }
+ else {
+ collection.setWhere( whereClause );
+ }
+ }
+
+ WhereJoinTable whereJoinTable = property.getAnnotation( WhereJoinTable.class );
+ String whereJoinTableClause = whereJoinTable == null ? null : whereJoinTable.clause();
+ if ( StringHelper.isNotEmpty( whereJoinTableClause ) ) {
+ if ( hasAssociationTable ) {
+ collection.setWhere( whereJoinTableClause );
+ }
+ else {
+ throw new AnnotationException(
+ "Illegal use of @WhereJoinTable on an association without join table:"
+ + StringHelper.qualify( propertyHolder.getPath(), propertyName )
+ );
+ }
+ }
+// This cannot happen in annotations since the second fetch is hardcoded to join
+// if ( ( ! collection.getManyToManyFilterMap().isEmpty() ||
collection.getManyToManyWhere() != null ) &&
+// collection.getFetchMode() == FetchMode.JOIN &&
+// collection.getElement().getFetchMode() != FetchMode.JOIN ) {
+// throw new MappingException(
+// "association with join table defining filter or where without join
fetching " +
+// "not valid within collection using join fetching [" +
collection.getRole() + "]"
+// );
+// }
+ }
+
+ private String getCondition(FilterJoinTable filter) {
+ //set filtering
+ String name = filter.name();
+ String cond = filter.condition();
+ return getCondition( cond, name );
+ }
+
+ private String getCondition(Filter filter) {
+ //set filtering
+ String name = filter.name();
+ String cond = filter.condition();
+ return getCondition( cond, name );
+ }
+
+ private String getCondition(String cond, String name) {
+ if ( BinderHelper.isDefault( cond ) ) {
+ cond = mappings.getFilterDefinition( name ).getDefaultFilterCondition();
+ if ( StringHelper.isEmpty( cond ) ) {
+ throw new AnnotationException(
+ "no filter condition found for filter " + name + " in "
+ + StringHelper.qualify( propertyHolder.getPath(), propertyName )
+ );
+ }
+ }
+ return cond;
+ }
+
+ public void setCache(Cache cacheAnn) {
+ if ( cacheAnn != null ) {
+ cacheRegionName = BinderHelper.isDefault( cacheAnn.region() ) ? null :
cacheAnn.region();
+ cacheConcurrencyStrategy = EntityBinder.getCacheConcurrencyStrategy( cacheAnn.usage()
);
+ }
+ else {
+ cacheConcurrencyStrategy = null;
+ cacheRegionName = null;
+ }
+ }
+
+ public void setOneToMany(boolean oneToMany) {
+ this.oneToMany = oneToMany;
+ }
+
+ public void setIndexColumn(IndexColumn indexColumn) {
+ this.indexColumn = indexColumn;
+ }
+
+ public void setMapKey(MapKey key) {
+ if ( key != null ) {
+ mapKeyPropertyName = key.name();
+ }
+ }
+
+ private static String buildOrderByClauseFromHql(String hqlOrderBy, PersistentClass
associatedClass, String role) {
+ String orderByString = null;
+ if ( hqlOrderBy != null ) {
+ List<String> properties = new ArrayList<String>();
+ List<String> ordering = new ArrayList<String>();
+ StringBuilder orderByBuffer = new StringBuilder();
+ if ( hqlOrderBy.length() == 0 ) {
+ //order by id
+ Iterator it = associatedClass.getIdentifier().getColumnIterator();
+ while ( it.hasNext() ) {
+ Selectable col = (Selectable) it.next();
+ orderByBuffer.append( col.getText() ).append( " asc" ).append( ",
" );
+ }
+ }
+ else {
+ StringTokenizer st = new StringTokenizer( hqlOrderBy, " ,", false );
+ String currentOrdering = null;
+ //FIXME make this code decent
+ while ( st.hasMoreTokens() ) {
+ String token = st.nextToken();
+ if ( isNonPropertyToken( token ) ) {
+ if ( currentOrdering != null ) {
+ throw new AnnotationException(
+ "Error while parsing HQL orderBy clause: " + hqlOrderBy
+ + " (" + role + ")"
+ );
+ }
+ currentOrdering = token;
+ }
+ else {
+ //Add ordering of the previous
+ if ( currentOrdering == null ) {
+ //default ordering
+ ordering.add( "asc" );
+ }
+ else {
+ ordering.add( currentOrdering );
+ currentOrdering = null;
+ }
+ properties.add( token );
+ }
+ }
+ ordering.remove( 0 ); //first one is the algorithm starter
+ // add last one ordering
+ if ( currentOrdering == null ) {
+ //default ordering
+ ordering.add( "asc" );
+ }
+ else {
+ ordering.add( currentOrdering );
+ currentOrdering = null;
+ }
+ int index = 0;
+
+ for (String property : properties) {
+ Property p = BinderHelper.findPropertyByName( associatedClass, property );
+ if ( p == null ) {
+ throw new AnnotationException(
+ "property from @OrderBy clause not found: "
+ + associatedClass.getEntityName() + "." + property
+ );
+ }
+ PersistentClass pc = p.getPersistentClass();
+ String table;
+ if ( pc == null ) {
+ //we are touching a @IdClass property, the pc is not set
+ //this means pc == associatedClass
+ //TODO check whether @ManyToOne @JoinTable in @IdClass used for @OrderBy works:
doh!
+ table = "";
+ }
+
+ else if (pc == associatedClass
+ || (associatedClass instanceof SingleTableSubclass && pc
+ .getMappedClass().isAssignableFrom(
+ associatedClass.getMappedClass()))) {
+ table = "";
+ } else {
+ table = pc.getTable().getQuotedName() + ".";
+ }
+
+ Iterator propertyColumns = p.getColumnIterator();
+ while ( propertyColumns.hasNext() ) {
+ Selectable column = (Selectable) propertyColumns.next();
+ orderByBuffer.append( table )
+ .append( column.getText() )
+ .append( " " )
+ .append( ordering.get( index ) )
+ .append( ", " );
+ }
+ index++;
+ }
+ }
+ orderByString = orderByBuffer.substring( 0, orderByBuffer.length() - 2 );
+ }
+ return orderByString;
+ }
+
+ private static String buildOrderByClauseFromHql(String hqlOrderBy, Component component,
String role) {
+ String orderByString = null;
+ if ( hqlOrderBy != null ) {
+ List<String> properties = new ArrayList<String>();
+ List<String> ordering = new ArrayList<String>();
+ StringBuilder orderByBuffer = new StringBuilder();
+ if ( hqlOrderBy.length() == 0 ) {
+ //TODO : Check that. Maybe order by key for maps
+ }
+ else {
+ StringTokenizer st = new StringTokenizer( hqlOrderBy, " ,", false );
+ String currentOrdering = null;
+ //FIXME make this code decent
+ while ( st.hasMoreTokens() ) {
+ String token = st.nextToken();
+ if ( isNonPropertyToken( token ) ) {
+ if ( currentOrdering != null ) {
+ throw new AnnotationException(
+ "Error while parsing HQL orderBy clause: " + hqlOrderBy
+ + " (" + role + ")"
+ );
+ }
+ currentOrdering = token;
+ }
+ else {
+ //Add ordering of the previous
+ if ( currentOrdering == null ) {
+ //default ordering
+ ordering.add( "asc" );
+ }
+ else {
+ ordering.add( currentOrdering );
+ currentOrdering = null;
+ }
+ properties.add( token );
+ }
+ }
+ ordering.remove( 0 ); //first one is the algorithm starter
+ // add last one ordering
+ if ( currentOrdering == null ) {
+ //default ordering
+ ordering.add( "asc" );
+ }
+ else {
+ ordering.add( currentOrdering );
+ currentOrdering = null;
+ }
+ int index = 0;
+
+ for (String property : properties) {
+ Property p = BinderHelper.findPropertyByName( component, property );
+ if ( p == null ) {
+ throw new AnnotationException(
+ "property from @OrderBy clause not found: "
+ + role + "." + property
+ );
+ }
+
+ Iterator propertyColumns = p.getColumnIterator();
+ while ( propertyColumns.hasNext() ) {
+ Selectable column = (Selectable) propertyColumns.next();
+ orderByBuffer.append( column.getText() )
+ .append( " " )
+ .append( ordering.get( index ) )
+ .append( ", " );
+ }
+ index++;
+ }
+
+ if ( orderByBuffer.length() >= 2 ) {
+ orderByString = orderByBuffer.substring( 0, orderByBuffer.length() - 2 );
+ }
+ }
+ }
+ return orderByString;
+ }
+
+ private static boolean isNonPropertyToken(String token) {
+ if ( " ".equals( token ) ) return true;
+ if ( ",".equals( token ) ) return true;
+ if ( token.equalsIgnoreCase( "desc" ) ) return true;
+ if ( token.equalsIgnoreCase( "asc" ) ) return true;
+ return false;
+ }
+
+ private static SimpleValue buildCollectionKey(
+ Collection collValue, Ejb3JoinColumn[] joinColumns, boolean cascadeDeleteEnabled,
+ XProperty property, ExtendedMappings mappings
+ ) {
+ //binding key reference using column
+ KeyValue keyVal;
+ //give a chance to override the referenced property name
+ //has to do that here because the referencedProperty creation happens in a FKSecondPass
for Many to one yuk!
+ if ( joinColumns.length > 0 && StringHelper.isNotEmpty(
joinColumns[0].getMappedBy() ) ) {
+ String entityName = joinColumns[0].getManyToManyOwnerSideEntityName() != null ?
+ "inverse__" + joinColumns[0].getManyToManyOwnerSideEntityName() :
+ joinColumns[0].getPropertyHolder().getEntityName();
+ String propRef = mappings.getPropertyReferencedAssociation(
+ entityName,
+ joinColumns[0].getMappedBy()
+ );
+ if ( propRef != null ) {
+ collValue.setReferencedPropertyName( propRef );
+ mappings.addPropertyReference( collValue.getOwnerEntityName(), propRef );
+ }
+ }
+ String propRef = collValue.getReferencedPropertyName();
+ if ( propRef == null ) {
+ keyVal = collValue.getOwner().getIdentifier();
+ }
+ else {
+ keyVal = (KeyValue) collValue.getOwner()
+ .getRecursiveProperty( propRef )
+ .getValue();
+ }
+ DependantValue key = new DependantValue( mappings, collValue.getCollectionTable(),
keyVal );
+ key.setTypeName( null );
+ Ejb3Column.checkPropertyConsistency( joinColumns, collValue.getOwnerEntityName() );
+ key.setNullable( joinColumns.length == 0 || joinColumns[0].isNullable() );
+ key.setUpdateable( joinColumns.length == 0 || joinColumns[0].isUpdatable() );
+ key.setCascadeDeleteEnabled( cascadeDeleteEnabled );
+ collValue.setKey( key );
+ ForeignKey fk = property != null ? property.getAnnotation( ForeignKey.class ) : null;
+ String fkName = fk != null ? fk.name() : "";
+ if ( !BinderHelper.isDefault( fkName ) ) key.setForeignKeyName( fkName );
+ return key;
+ }
+
+ protected void bindManyToManySecondPass(
+ Collection collValue,
+ Map persistentClasses,
+ Ejb3JoinColumn[] joinColumns,
+ Ejb3JoinColumn[] inverseJoinColumns,
+ Ejb3Column[] elementColumns,
+ boolean isEmbedded,
+ XClass collType,
+ boolean ignoreNotFound, boolean unique,
+ boolean cascadeDeleteEnabled,
+ TableBinder associationTableBinder, XProperty property, PropertyHolder
parentPropertyHolder,
+ String hqlOrderBy, ExtendedMappings mappings
+ ) throws MappingException {
+
+ PersistentClass collectionEntity = (PersistentClass) persistentClasses.get(
collType.getName() );
+ boolean isCollectionOfEntities = collectionEntity != null;
+ ManyToAny anyAnn = property.getAnnotation( ManyToAny.class );
+ if ( log.isDebugEnabled() ) {
+ String path = collValue.getOwnerEntityName() + "." +
joinColumns[0].getPropertyName();
+ if ( isCollectionOfEntities && unique ) {
+ log.debug( "Binding a OneToMany: {} through an association table", path );
+ }
+ else if ( isCollectionOfEntities ) {
+ log.debug( "Binding as ManyToMany: {}", path );
+ }
+ else if ( anyAnn != null ) {
+ log.debug( "Binding a ManyToAny: {}", path );
+ }
+ else {
+ log.debug( "Binding a collection of element: {}", path );
+ }
+ }
+ //check for user error
+ if ( !isCollectionOfEntities ) {
+ if ( property.isAnnotationPresent( ManyToMany.class ) || property.isAnnotationPresent(
OneToMany.class ) ) {
+ String path = collValue.getOwnerEntityName() + "." +
joinColumns[0].getPropertyName();
+ throw new AnnotationException(
+ "Use of @OneToMany or @ManyToMany targeting an unmapped class: " + path +
"[" + collType + "]"
+ );
+ }
+ else if ( anyAnn != null ) {
+ if ( parentPropertyHolder.getJoinTable( property ) == null ) {
+ String path = collValue.getOwnerEntityName() + "." +
joinColumns[0].getPropertyName();
+ throw new AnnotationException(
+ "@JoinTable is mandatory when @ManyToAny is used: " + path
+ );
+ }
+ }
+ else {
+ JoinTable joinTableAnn = parentPropertyHolder.getJoinTable( property );
+ if ( joinTableAnn != null && joinTableAnn.inverseJoinColumns().length > 0
) {
+ String path = collValue.getOwnerEntityName() + "." +
joinColumns[0].getPropertyName();
+ throw new AnnotationException(
+ "Use of @JoinTable.inverseJoinColumns targeting an unmapped class: " +
path + "[" + collType + "]"
+ );
+ }
+ }
+ }
+
+ boolean mappedBy = !BinderHelper.isDefault( joinColumns[0].getMappedBy() );
+ if ( mappedBy ) {
+ if ( !isCollectionOfEntities ) {
+ StringBuilder error = new StringBuilder( 80 )
+ .append(
+ "Collection of elements must not have mappedBy or association reference an
unmapped entity: "
+ )
+ .append( collValue.getOwnerEntityName() )
+ .append( "." )
+ .append( joinColumns[0].getPropertyName() );
+ throw new AnnotationException( error.toString() );
+ }
+ Property otherSideProperty;
+ try {
+ otherSideProperty = collectionEntity.getRecursiveProperty(
joinColumns[0].getMappedBy() );
+ }
+ catch (MappingException e) {
+ StringBuilder error = new StringBuilder( 80 );
+ error.append( "mappedBy reference an unknown target entity property: " )
+ .append( collType ).append( "." ).append( joinColumns[0].getMappedBy() )
+ .append( " in " )
+ .append( collValue.getOwnerEntityName() )
+ .append( "." )
+ .append( joinColumns[0].getPropertyName() );
+ throw new AnnotationException( error.toString() );
+ }
+ Table table;
+ if ( otherSideProperty.getValue() instanceof Collection ) {
+ //this is a collection on the other side
+ table = ( (Collection) otherSideProperty.getValue() ).getCollectionTable();
+ }
+ else {
+ //This is a ToOne with a @JoinTable or a regular property
+ table = otherSideProperty.getValue().getTable();
+ }
+ collValue.setCollectionTable( table );
+ String entityName = collectionEntity.getEntityName();
+ for (Ejb3JoinColumn column : joinColumns) {
+ //column.setDefaultColumnHeader( joinColumns[0].getMappedBy() ); //seems not to be
used, make sense
+ column.setManyToManyOwnerSideEntityName( entityName );
+ }
+ }
+ else {
+ //TODO: only for implicit columns?
+ //FIXME NamingStrategy
+ for (Ejb3JoinColumn column : joinColumns) {
+ String mappedByProperty = mappings.getFromMappedBy(
+ collValue.getOwnerEntityName(), column.getPropertyName()
+ );
+ Table ownerTable = collValue.getOwner().getTable();
+ column.setMappedBy(
+ collValue.getOwner().getEntityName(), mappings.getLogicalTableName( ownerTable ),
+ mappedByProperty
+ );
+// String header = ( mappedByProperty == null ) ? mappings.getLogicalTableName(
ownerTable ) : mappedByProperty;
+// column.setDefaultColumnHeader( header );
+ }
+ if ( StringHelper.isEmpty( associationTableBinder.getName() ) ) {
+ //default value
+ associationTableBinder.setDefaultName(
+ collValue.getOwner().getEntityName(),
+ mappings.getLogicalTableName( collValue.getOwner().getTable() ),
+ collectionEntity != null ? collectionEntity.getEntityName() : null,
+ collectionEntity != null ? mappings.getLogicalTableName(
collectionEntity.getTable() ) : null,
+ joinColumns[0].getPropertyName()
+ );
+ }
+ associationTableBinder.setJPA2ElementCollection( !isCollectionOfEntities &&
property.isAnnotationPresent( ElementCollection.class ));
+ collValue.setCollectionTable( associationTableBinder.bind() );
+ }
+ bindFilters( isCollectionOfEntities );
+ bindCollectionSecondPass( collValue, collectionEntity, joinColumns,
cascadeDeleteEnabled, property, mappings );
+
+ ManyToOne element = null;
+ if ( isCollectionOfEntities ) {
+ element =
+ new ManyToOne( mappings, collValue.getCollectionTable() );
+ collValue.setElement( element );
+ element.setReferencedEntityName( collType.getName() );
+ //element.setFetchMode( fetchMode );
+ //element.setLazy( fetchMode != FetchMode.JOIN );
+ //make the second join non lazy
+ element.setFetchMode( FetchMode.JOIN );
+ element.setLazy( false );
+ element.setIgnoreNotFound( ignoreNotFound );
+ // as per 11.1.38 of JPA-2 spec, default to primary key if no column is specified by
@OrderBy.
+ if ( hqlOrderBy != null ) {
+ collValue.setManyToManyOrdering(
+ buildOrderByClauseFromHql( hqlOrderBy, collectionEntity, collValue.getRole() )
+ );
+ }
+ ForeignKey fk = property != null ? property.getAnnotation( ForeignKey.class ) : null;
+ String fkName = fk != null ? fk.inverseName() : "";
+ if ( !BinderHelper.isDefault( fkName ) ) element.setForeignKeyName( fkName );
+ }
+ else if ( anyAnn != null ) {
+ //@ManyToAny
+ //Make sure that collTyp is never used during the @ManyToAny branch: it will be set to
void.class
+ PropertyData inferredData = new PropertyInferredData(null, property,
"unsupported", mappings.getReflectionManager() );
+ //override the table
+ for (Ejb3Column column : inverseJoinColumns) {
+ column.setTable( collValue.getCollectionTable() );
+ }
+ Any any = BinderHelper.buildAnyValue( anyAnn.metaDef(), inverseJoinColumns,
anyAnn.metaColumn(),
+ inferredData, cascadeDeleteEnabled, Nullability.NO_CONSTRAINT,
+ propertyHolder, new EntityBinder(), true, mappings );
+ collValue.setElement( any );
+ }
+ else {
+ XClass elementClass;
+ AnnotatedClassType classType;
+
+ PropertyHolder holder = null;
+ if ( BinderHelper.PRIMITIVE_NAMES.contains( collType.getName() ) ) {
+ classType = AnnotatedClassType.NONE;
+ elementClass = null;
+ }
+ else {
+ elementClass = collType;
+ classType = mappings.getClassType( elementClass );
+
+ holder = PropertyHolderBuilder.buildPropertyHolder(
+ collValue,
+ collValue.getRole(),
+ elementClass,
+ property, parentPropertyHolder, mappings
+ );
+ //force in case of attribute override
+ boolean attributeOverride = property.isAnnotationPresent( AttributeOverride.class )
+ || property.isAnnotationPresent( AttributeOverrides.class );
+ if ( isEmbedded || attributeOverride ) {
+ classType = AnnotatedClassType.EMBEDDABLE;
+ }
+ }
+
+ if ( AnnotatedClassType.EMBEDDABLE.equals( classType ) ) {
+ EntityBinder entityBinder = new EntityBinder();
+ PersistentClass owner = collValue.getOwner();
+ boolean isPropertyAnnotated;
+ //FIXME support @Access for collection of elements
+ //String accessType = access != null ? access.value() : null;
+ if ( owner.getIdentifierProperty() != null ) {
+ isPropertyAnnotated =
owner.getIdentifierProperty().getPropertyAccessorName().equals( "property" );
+ }
+ else if ( owner.getIdentifierMapper() != null &&
owner.getIdentifierMapper().getPropertySpan() > 0 ) {
+ Property prop = (Property)
owner.getIdentifierMapper().getPropertyIterator().next();
+ isPropertyAnnotated = prop.getPropertyAccessorName().equals( "property"
);
+ }
+ else {
+ throw new AssertionFailure( "Unable to guess collection property accessor
name" );
+ }
+
+ PropertyData inferredData;
+ if ( isMap() ) {
+ //"value" is the JPA 2 prefix for map values (used to be
"element")
+ if ( isHibernateExtensionMapping() ) {
+ inferredData = new PropertyPreloadedData( AccessType.PROPERTY, "element",
elementClass );
+ }
+ else {
+ inferredData = new PropertyPreloadedData( AccessType.PROPERTY, "value",
elementClass );
+ }
+ }
+ else {
+ if ( isHibernateExtensionMapping() ) {
+ inferredData = new PropertyPreloadedData( AccessType.PROPERTY, "element",
elementClass );
+ }
+ else {
+ //"collection&&element" is not a valid property name =>
placeholder
+ inferredData = new PropertyPreloadedData( AccessType.PROPERTY,
"collection&&element", elementClass );
+ }
+ }
+ //TODO be smart with isNullable
+ Component component = AnnotationBinder.fillComponent(
+ holder, inferredData, isPropertyAnnotated ? AccessType.PROPERTY : AccessType.FIELD,
true,
+ entityBinder, false, false,
+ true, mappings, inheritanceStatePerClass
+ );
+
+ collValue.setElement( component );
+
+ if ( StringHelper.isNotEmpty( hqlOrderBy ) ) {
+ String path = collValue.getOwnerEntityName() + "." +
joinColumns[0].getPropertyName();
+ String orderBy = buildOrderByClauseFromHql( hqlOrderBy, component, path );
+ if ( orderBy != null ) {
+ collValue.setOrderBy( orderBy );
+ }
+ }
+ }
+ else {
+ SimpleValueBinder elementBinder = new SimpleValueBinder();
+ elementBinder.setMappings( mappings );
+ elementBinder.setReturnedClassName( collType.getName() );
+ if ( elementColumns == null || elementColumns.length == 0 ) {
+ elementColumns = new Ejb3Column[1];
+ Ejb3Column column = new Ejb3Column();
+ column.setImplicit( false );
+ //not following the spec but more clean
+ column.setNullable( true );
+ column.setLength( Ejb3Column.DEFAULT_COLUMN_LENGTH );
+ column.setLogicalColumnName( Collection.DEFAULT_ELEMENT_COLUMN_NAME );
+ //TODO create an EMPTY_JOINS collection
+ column.setJoins( new HashMap<String, Join>() );
+ column.setMappings( mappings );
+ column.bind();
+ elementColumns[0] = column;
+ }
+ //override the table
+ for (Ejb3Column column : elementColumns) {
+ column.setTable( collValue.getCollectionTable() );
+ }
+ elementBinder.setColumns( elementColumns );
+ elementBinder.setType( property, elementClass );
+ collValue.setElement( elementBinder.make() );
+ }
+ }
+
+ checkFilterConditions( collValue );
+
+ //FIXME: do optional = false
+ if ( isCollectionOfEntities ) {
+ bindManytoManyInverseFk( collectionEntity, inverseJoinColumns, element, unique,
mappings );
+ }
+
+ }
+
+ private static void checkFilterConditions(Collection collValue) {
+ //for now it can't happen, but sometime soon...
+ if ( ( collValue.getFilterMap().size() != 0 || StringHelper.isNotEmpty(
collValue.getWhere() ) ) &&
+ collValue.getFetchMode() == FetchMode.JOIN &&
+ !( collValue.getElement() instanceof SimpleValue ) && //SimpleValue
(CollectionOfElements) are always SELECT but it does not matter
+ collValue.getElement().getFetchMode() != FetchMode.JOIN ) {
+ throw new MappingException(
+ "@ManyToMany or @CollectionOfElements defining filter or where without join
fetching "
+ + "not valid within collection using join fetching[" +
collValue.getRole() + "]"
+ );
+ }
+ }
+
+ private static void bindCollectionSecondPass(
+ Collection collValue, PersistentClass collectionEntity, Ejb3JoinColumn[] joinColumns,
+ boolean cascadeDeleteEnabled, XProperty property,
+ ExtendedMappings mappings
+ ) {
+ BinderHelper.createSyntheticPropertyReference(
+ joinColumns, collValue.getOwner(), collectionEntity, collValue, false, mappings
+ );
+ SimpleValue key = buildCollectionKey( collValue, joinColumns, cascadeDeleteEnabled,
property, mappings );
+ if ( property.isAnnotationPresent( ElementCollection.class ) &&
joinColumns.length > 0 ) {
+ joinColumns[0].setJPA2ElementCollection( true );
+ }
+ TableBinder.bindFk( collValue.getOwner(), collectionEntity, joinColumns, key, false,
mappings );
+ }
+
+ public void setCascadeDeleteEnabled(boolean onDeleteCascade) {
+ this.cascadeDeleteEnabled = onDeleteCascade;
+ }
+
+ private String safeCollectionRole() {
+ if ( propertyHolder != null ) {
+ return propertyHolder.getEntityName() + "." + propertyName;
+ }
+ else {
+ return "";
+ }
+ }
+
+
+ /**
+ * bind the inverse FK of a ManyToMany
+ * If we are in a mappedBy case, read the columns from the associated
+ * colletion element
+ * Otherwise delegates to the usual algorithm
+ */
+ public static void bindManytoManyInverseFk(
+ PersistentClass referencedEntity, Ejb3JoinColumn[] columns, SimpleValue value, boolean
unique,
+ ExtendedMappings mappings
+ ) {
+ final String mappedBy = columns[0].getMappedBy();
+ if ( StringHelper.isNotEmpty( mappedBy ) ) {
+ final Property property = referencedEntity.getRecursiveProperty( mappedBy );
+ Iterator mappedByColumns;
+ if ( property.getValue() instanceof Collection ) {
+ mappedByColumns = ( (Collection) property.getValue() ).getKey().getColumnIterator();
+ }
+ else {
+ //find the appropriate reference key, can be in a join
+ Iterator joinsIt = referencedEntity.getJoinIterator();
+ KeyValue key = null;
+ while ( joinsIt.hasNext() ) {
+ Join join = (Join) joinsIt.next();
+ if ( join.containsProperty( property ) ) {
+ key = join.getKey();
+ break;
+ }
+ }
+ if ( key == null ) key = property.getPersistentClass().getIdentifier();
+ mappedByColumns = key.getColumnIterator();
+ }
+ while ( mappedByColumns.hasNext() ) {
+ Column column = (Column) mappedByColumns.next();
+ columns[0].linkValueUsingAColumnCopy( column, value );
+ }
+ String referencedPropertyName =
+ mappings.getPropertyReferencedAssociation(
+ "inverse__" + referencedEntity.getEntityName(), mappedBy
+ );
+ if ( referencedPropertyName != null ) {
+ //TODO always a many to one?
+ ( (ManyToOne) value ).setReferencedPropertyName( referencedPropertyName );
+ mappings.addUniquePropertyReference( referencedEntity.getEntityName(),
referencedPropertyName );
+ }
+ value.createForeignKey();
+ }
+ else {
+ BinderHelper.createSyntheticPropertyReference( columns, referencedEntity, null, value,
true, mappings );
+ TableBinder.bindFk( referencedEntity, null, columns, value, unique, mappings );
+ }
+ }
+
+ public void setFkJoinColumns(Ejb3JoinColumn[] ejb3JoinColumns) {
+ this.fkJoinColumns = ejb3JoinColumns;
+ }
+
+ public void setExplicitAssociationTable(boolean explicitAssocTable) {
+ this.isExplicitAssociationTable = explicitAssocTable;
+ }
+
+ public void setElementColumns(Ejb3Column[] elementColumns) {
+ this.elementColumns = elementColumns;
+ }
+
+ public void setEmbedded(boolean annotationPresent) {
+ this.isEmbedded = annotationPresent;
+ }
+
+ public void setProperty(XProperty property) {
+ this.property = property;
+ }
+
+ public void setIgnoreNotFound(boolean ignoreNotFound) {
+ this.ignoreNotFound = ignoreNotFound;
+ }
+
+ public void setMapKeyColumns(Ejb3Column[] mapKeyColumns) {
+ this.mapKeyColumns = mapKeyColumns;
+ }
+
+ public void setMapKeyManyToManyColumns(Ejb3JoinColumn[] mapJoinColumns) {
+ this.mapKeyManyToManyColumns = mapJoinColumns;
+ }
+
+ public void setLocalGenerators(HashMap<String, IdGenerator> localGenerators) {
+ this.localGenerators = localGenerators;
+ }
+}
\ No newline at end of file
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/CustomizableColumns.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/CustomizableColumns.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/annotations/CustomizableColumns.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/CustomizableColumns.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,26 @@
+package org.hibernate.cfg.annotations;
+
+import java.lang.annotation.Annotation;
+import javax.persistence.Column;
+
+import org.hibernate.annotations.Columns;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@SuppressWarnings({ "ClassExplicitlyAnnotation" })
+public class CustomizableColumns implements Columns {
+ private final Column[] columns;
+
+ public CustomizableColumns(Column[] columns) {
+ this.columns = columns;
+ }
+
+ public Column[] columns() {
+ return columns;
+ }
+
+ public Class<? extends Annotation> annotationType() {
+ return Columns.class;
+ }
+}
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,914 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg.annotations;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import javax.persistence.Access;
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.PrimaryKeyJoinColumn;
+import javax.persistence.SecondaryTable;
+import javax.persistence.SecondaryTables;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.AssertionFailure;
+import org.hibernate.EntityMode;
+import org.hibernate.MappingException;
+import org.hibernate.annotations.BatchSize;
+import org.hibernate.annotations.Cache;
+import org.hibernate.annotations.CacheConcurrencyStrategy;
+import org.hibernate.annotations.FetchMode;
+import org.hibernate.annotations.ForceDiscriminator;
+import org.hibernate.annotations.Immutable;
+import org.hibernate.annotations.Loader;
+import org.hibernate.annotations.OptimisticLockType;
+import org.hibernate.annotations.Persister;
+import org.hibernate.annotations.PolymorphismType;
+import org.hibernate.annotations.Proxy;
+import org.hibernate.annotations.SQLDelete;
+import org.hibernate.annotations.SQLDeleteAll;
+import org.hibernate.annotations.SQLInsert;
+import org.hibernate.annotations.SQLUpdate;
+import org.hibernate.annotations.Subselect;
+import org.hibernate.annotations.Synchronize;
+import org.hibernate.annotations.Tables;
+import org.hibernate.annotations.Tuplizer;
+import org.hibernate.annotations.Tuplizers;
+import org.hibernate.annotations.Where;
+import org.hibernate.annotations.common.reflection.XAnnotatedElement;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.cfg.AccessType;
+import org.hibernate.cfg.AnnotationBinder;
+import org.hibernate.cfg.BinderHelper;
+import org.hibernate.cfg.Ejb3JoinColumn;
+import org.hibernate.cfg.ExtendedMappings;
+import org.hibernate.cfg.InheritanceState;
+import org.hibernate.cfg.PropertyHolder;
+import org.hibernate.cfg.ObjectNameSource;
+import org.hibernate.cfg.NamingStrategy;
+import org.hibernate.cfg.ObjectNameNormalizer;
+import org.hibernate.cfg.UniqueConstraintHolder;
+import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
+import org.hibernate.engine.FilterDefinition;
+import org.hibernate.engine.Versioning;
+import org.hibernate.mapping.DependantValue;
+import org.hibernate.mapping.Join;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.RootClass;
+import org.hibernate.mapping.SimpleValue;
+import org.hibernate.mapping.Table;
+import org.hibernate.mapping.TableOwner;
+import org.hibernate.mapping.Value;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.StringHelper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Stateful holder and processor for binding Entity information
+ *
+ * @author Emmanuel Bernard
+ */
+public class EntityBinder {
+ private String name;
+ private XClass annotatedClass;
+ private PersistentClass persistentClass;
+ private ExtendedMappings mappings;
+ private Logger log = LoggerFactory.getLogger( EntityBinder.class );
+ private String discriminatorValue = "";
+ private boolean dynamicInsert;
+ private boolean dynamicUpdate;
+ private boolean explicitHibernateEntityAnnotation;
+ private OptimisticLockType optimisticLockType;
+ private PolymorphismType polymorphismType;
+ private boolean selectBeforeUpdate;
+ private int batchSize;
+ private boolean lazy;
+ private XClass proxyClass;
+ private String where;
+ private java.util.Map<String, Join> secondaryTables = new HashMap<String,
Join>();
+ private java.util.Map<String, Object> secondaryTableJoins = new HashMap<String,
Object>();
+ private String cacheConcurrentStrategy;
+ private String cacheRegion;
+ private java.util.Map<String, String> filters = new HashMap<String,
String>();
+ private InheritanceState inheritanceState;
+ private boolean ignoreIdAnnotations;
+ private boolean cacheLazyProperty;
+ private AccessType propertyAccessType = AccessType.DEFAULT;
+ private boolean wrapIdsInEmbeddedComponents;
+ private String subselect;
+
+
+ public boolean wrapIdsInEmbeddedComponents() {
+ return wrapIdsInEmbeddedComponents;
+ }
+
+ /**
+ * Use as a fake one for Collection of elements
+ */
+ public EntityBinder() {
+ }
+
+ public EntityBinder(
+ Entity ejb3Ann, org.hibernate.annotations.Entity hibAnn,
+ XClass annotatedClass, PersistentClass persistentClass,
+ ExtendedMappings mappings
+ ) {
+ this.mappings = mappings;
+ this.persistentClass = persistentClass;
+ this.annotatedClass = annotatedClass;
+ bindEjb3Annotation( ejb3Ann );
+ bindHibernateAnnotation( hibAnn );
+ }
+
+ private void bindHibernateAnnotation(org.hibernate.annotations.Entity hibAnn) {
+ if ( hibAnn != null ) {
+ dynamicInsert = hibAnn.dynamicInsert();
+ dynamicUpdate = hibAnn.dynamicUpdate();
+ optimisticLockType = hibAnn.optimisticLock();
+ selectBeforeUpdate = hibAnn.selectBeforeUpdate();
+ polymorphismType = hibAnn.polymorphism();
+ explicitHibernateEntityAnnotation = true;
+ //persister handled in bind
+ }
+ else {
+ //default values when the annotation is not there
+ dynamicInsert = false;
+ dynamicUpdate = false;
+ optimisticLockType = OptimisticLockType.VERSION;
+ polymorphismType = PolymorphismType.IMPLICIT;
+ selectBeforeUpdate = false;
+ }
+ }
+
+ private void bindEjb3Annotation(Entity ejb3Ann) {
+ if ( ejb3Ann == null ) throw new AssertionFailure( "@Entity should always be not
null" );
+ if ( BinderHelper.isDefault( ejb3Ann.name() ) ) {
+ name = StringHelper.unqualify( annotatedClass.getName() );
+ }
+ else {
+ name = ejb3Ann.name();
+ }
+ }
+
+ public void setDiscriminatorValue(String discriminatorValue) {
+ this.discriminatorValue = discriminatorValue;
+ }
+
+ public void bindEntity() {
+ persistentClass.setAbstract( annotatedClass.isAbstract() );
+ persistentClass.setClassName( annotatedClass.getName() );
+ persistentClass.setNodeName( name );
+ //persistentClass.setDynamic(false); //no longer needed with the Entity name
refactoring?
+ persistentClass.setEntityName( annotatedClass.getName() );
+ bindDiscriminatorValue();
+
+ persistentClass.setLazy( lazy );
+ if ( proxyClass != null ) {
+ persistentClass.setProxyInterfaceName( proxyClass.getName() );
+ }
+ persistentClass.setDynamicInsert( dynamicInsert );
+ persistentClass.setDynamicUpdate( dynamicUpdate );
+
+ if ( persistentClass instanceof RootClass ) {
+ RootClass rootClass = (RootClass) persistentClass;
+ boolean mutable = true;
+ //priority on @Immutable, then @Entity.mutable()
+ if ( annotatedClass.isAnnotationPresent( Immutable.class ) ) {
+ mutable = false;
+ }
+ else {
+ org.hibernate.annotations.Entity entityAnn =
+ annotatedClass.getAnnotation( org.hibernate.annotations.Entity.class );
+ if ( entityAnn != null ) {
+ mutable = entityAnn.mutable();
+ }
+ }
+ rootClass.setMutable( mutable );
+ rootClass.setExplicitPolymorphism( isExplicitPolymorphism( polymorphismType ) );
+ if ( StringHelper.isNotEmpty( where ) ) rootClass.setWhere( where );
+ if ( cacheConcurrentStrategy != null ) {
+ rootClass.setCacheConcurrencyStrategy( cacheConcurrentStrategy );
+ rootClass.setCacheRegionName( cacheRegion );
+ rootClass.setLazyPropertiesCacheable( cacheLazyProperty );
+ }
+ rootClass.setForceDiscriminator( annotatedClass.isAnnotationPresent(
ForceDiscriminator.class ) );
+ }
+ else {
+ if ( explicitHibernateEntityAnnotation ) {
+ log.warn( "(a)org.hibernate.annotations.Entity used on a non root entity: ignored
for {}",
+ annotatedClass.getName() );
+ }
+ if ( annotatedClass.isAnnotationPresent( Immutable.class ) ) {
+ log.warn( "@Immutable used on a non root entity: ignored for {}",
+ annotatedClass.getName() );
+ }
+ }
+ persistentClass.setOptimisticLockMode( getVersioning( optimisticLockType ) );
+ persistentClass.setSelectBeforeUpdate( selectBeforeUpdate );
+
+ //set persister if needed
+ //@Persister has precedence over @Entity.persister
+ Persister persisterAnn = annotatedClass.getAnnotation( Persister.class );
+ Class persister = null;
+ if ( persisterAnn != null ) {
+ persister = persisterAnn.impl();
+ }
+ else {
+ org.hibernate.annotations.Entity entityAnn = annotatedClass.getAnnotation(
org.hibernate.annotations.Entity.class );
+ if ( entityAnn != null && !BinderHelper.isDefault( entityAnn.persister() ) )
{
+ try {
+ persister = ReflectHelper.classForName( entityAnn.persister() );
+ }
+ catch (ClassNotFoundException cnfe) {
+ throw new AnnotationException( "Could not find persister class: " +
persister );
+ }
+ }
+ }
+ if ( persister != null ) persistentClass.setEntityPersisterClass( persister );
+
+ persistentClass.setBatchSize( batchSize );
+
+ //SQL overriding
+ SQLInsert sqlInsert = annotatedClass.getAnnotation( SQLInsert.class );
+ SQLUpdate sqlUpdate = annotatedClass.getAnnotation( SQLUpdate.class );
+ SQLDelete sqlDelete = annotatedClass.getAnnotation( SQLDelete.class );
+ SQLDeleteAll sqlDeleteAll = annotatedClass.getAnnotation( SQLDeleteAll.class );
+ Loader loader = annotatedClass.getAnnotation( Loader.class );
+
+ if ( sqlInsert != null ) {
+ persistentClass.setCustomSQLInsert( sqlInsert.sql().trim(), sqlInsert.callable(),
+ ExecuteUpdateResultCheckStyle.parse( sqlInsert.check().toString().toLowerCase() )
+ );
+
+ }
+ if ( sqlUpdate != null ) {
+ persistentClass.setCustomSQLUpdate( sqlUpdate.sql(), sqlUpdate.callable(),
+ ExecuteUpdateResultCheckStyle.parse( sqlUpdate.check().toString().toLowerCase() )
+ );
+ }
+ if ( sqlDelete != null ) {
+ persistentClass.setCustomSQLDelete( sqlDelete.sql(), sqlDelete.callable(),
+ ExecuteUpdateResultCheckStyle.parse( sqlDelete.check().toString().toLowerCase() )
+ );
+ }
+ if ( sqlDeleteAll != null ) {
+ persistentClass.setCustomSQLDelete( sqlDeleteAll.sql(), sqlDeleteAll.callable(),
+ ExecuteUpdateResultCheckStyle.parse( sqlDeleteAll.check().toString().toLowerCase()
)
+ );
+ }
+ if ( loader != null ) {
+ persistentClass.setLoaderName( loader.namedQuery() );
+ }
+
+ if ( annotatedClass.isAnnotationPresent( Synchronize.class )) {
+ Synchronize synchronizedWith = annotatedClass.getAnnotation(Synchronize.class);
+
+ String [] tables = synchronizedWith.value();
+ for (String table : tables) {
+ persistentClass.addSynchronizedTable(table);
+ }
+ }
+
+ if ( annotatedClass.isAnnotationPresent(Subselect.class )) {
+ Subselect subselect = annotatedClass.getAnnotation(Subselect.class);
+ this.subselect = subselect.value();
+ }
+
+ //tuplizers
+ if ( annotatedClass.isAnnotationPresent( Tuplizers.class ) ) {
+ for (Tuplizer tuplizer : annotatedClass.getAnnotation( Tuplizers.class ).value()) {
+ EntityMode mode = EntityMode.parse( tuplizer.entityMode() );
+ persistentClass.addTuplizer( mode, tuplizer.impl().getName() );
+ }
+ }
+ if ( annotatedClass.isAnnotationPresent( Tuplizer.class ) ) {
+ Tuplizer tuplizer = annotatedClass.getAnnotation( Tuplizer.class );
+ EntityMode mode = EntityMode.parse( tuplizer.entityMode() );
+ persistentClass.addTuplizer( mode, tuplizer.impl().getName() );
+ }
+
+ if ( !inheritanceState.hasParents() ) {
+ for ( Map.Entry<String, String> filter : filters.entrySet() ) {
+ String filterName = filter.getKey();
+ String cond = filter.getValue();
+ if ( BinderHelper.isDefault( cond ) ) {
+ FilterDefinition definition = mappings.getFilterDefinition( filterName );
+ cond = definition == null ? null : definition.getDefaultFilterCondition();
+ if ( StringHelper.isEmpty( cond ) ) {
+ throw new AnnotationException(
+ "no filter condition found for filter " + filterName + " in "
+ this.name
+ );
+ }
+ }
+ persistentClass.addFilter( filterName, cond );
+ }
+ }
+ else {
+ if ( filters.size() > 0 ) {
+ log.warn( "@Filter not allowed on subclasses (ignored): {}",
persistentClass.getEntityName() );
+ }
+ }
+ log.debug( "Import with entity name {}", name );
+ try {
+ mappings.addImport( persistentClass.getEntityName(), name );
+ String entityName = persistentClass.getEntityName();
+ if ( !entityName.equals( name ) ) {
+ mappings.addImport( entityName, entityName );
+ }
+ }
+ catch (MappingException me) {
+ throw new AnnotationException( "Use of the same entity name twice: " + name,
me );
+ }
+ }
+
+ public void bindDiscriminatorValue() {
+ if ( StringHelper.isEmpty( discriminatorValue ) ) {
+ Value discriminator = persistentClass.getDiscriminator();
+ if ( discriminator == null ) {
+ persistentClass.setDiscriminatorValue( name );
+ }
+ else if ( "character".equals( discriminator.getType().getName() ) ) {
+ throw new AnnotationException(
+ "Using default @DiscriminatorValue for a discriminator of type CHAR is not
safe"
+ );
+ }
+ else if ( "integer".equals( discriminator.getType().getName() ) ) {
+ persistentClass.setDiscriminatorValue( String.valueOf( name.hashCode() ) );
+ }
+ else {
+ persistentClass.setDiscriminatorValue( name ); //Spec compliant
+ }
+ }
+ else {
+ //persistentClass.getDiscriminator()
+ persistentClass.setDiscriminatorValue( discriminatorValue );
+ }
+ }
+
+ int getVersioning(OptimisticLockType type) {
+ switch ( type ) {
+ case VERSION:
+ return Versioning.OPTIMISTIC_LOCK_VERSION;
+ case NONE:
+ return Versioning.OPTIMISTIC_LOCK_NONE;
+ case DIRTY:
+ return Versioning.OPTIMISTIC_LOCK_DIRTY;
+ case ALL:
+ return Versioning.OPTIMISTIC_LOCK_ALL;
+ default:
+ throw new AssertionFailure( "optimistic locking not supported: " + type );
+ }
+ }
+
+ private boolean isExplicitPolymorphism(PolymorphismType type) {
+ switch ( type ) {
+ case IMPLICIT:
+ return false;
+ case EXPLICIT:
+ return true;
+ default:
+ throw new AssertionFailure( "Unknown polymorphism type: " + type );
+ }
+ }
+
+ public void setBatchSize(BatchSize sizeAnn) {
+ if ( sizeAnn != null ) {
+ batchSize = sizeAnn.size();
+ }
+ else {
+ batchSize = -1;
+ }
+ }
+
+ @SuppressWarnings({ "unchecked" })
+ public void setProxy(Proxy proxy) {
+ if ( proxy != null ) {
+ lazy = proxy.lazy();
+ if ( !lazy ) {
+ proxyClass = null;
+ }
+ else {
+ if ( AnnotationBinder.isDefault(
+ mappings.getReflectionManager().toXClass( proxy.proxyClass() ), mappings
+ ) ) {
+ proxyClass = annotatedClass;
+ }
+ else {
+ proxyClass = mappings.getReflectionManager().toXClass( proxy.proxyClass() );
+ }
+ }
+ }
+ else {
+ lazy = true; //needed to allow association lazy loading.
+ proxyClass = annotatedClass;
+ }
+ }
+
+ public void setWhere(Where whereAnn) {
+ if ( whereAnn != null ) {
+ where = whereAnn.clause();
+ }
+ }
+
+ public void setWrapIdsInEmbeddedComponents(boolean wrapIdsInEmbeddedComponents) {
+ this.wrapIdsInEmbeddedComponents = wrapIdsInEmbeddedComponents;
+ }
+
+
+ private static class EntityTableObjectNameSource implements ObjectNameSource {
+ private final String explicitName;
+ private final String logicalName;
+
+ private EntityTableObjectNameSource(String explicitName, String entityName) {
+ this.explicitName = explicitName;
+ this.logicalName = StringHelper.isNotEmpty( explicitName )
+ ? explicitName
+ : StringHelper.unqualify( entityName );
+ }
+
+ public String getExplicitName() {
+ return explicitName;
+ }
+
+ public String getLogicalName() {
+ return logicalName;
+ }
+ }
+
+ private static class EntityTableNamingStrategyHelper implements
ObjectNameNormalizer.NamingStrategyHelper {
+ private final String entityName;
+
+ private EntityTableNamingStrategyHelper(String entityName) {
+ this.entityName = entityName;
+ }
+
+ public String determineImplicitName(NamingStrategy strategy) {
+ return strategy.classToTableName( entityName );
+ }
+
+ public String handleExplicitName(NamingStrategy strategy, String name) {
+ return strategy.tableName( name );
+ }
+ }
+
+ public void bindTable(
+ String schema, String catalog,
+ String tableName, List<UniqueConstraintHolder> uniqueConstraints,
+ String constraints, Table denormalizedSuperclassTable) {
+ EntityTableObjectNameSource tableNameContext = new EntityTableObjectNameSource(
tableName, name );
+ EntityTableNamingStrategyHelper namingStrategyHelper = new
EntityTableNamingStrategyHelper( name );
+ final Table table = TableBinder.buildAndFillTable(
+ schema,
+ catalog,
+ tableNameContext,
+ namingStrategyHelper,
+ persistentClass.isAbstract(),
+ uniqueConstraints,
+ constraints,
+ denormalizedSuperclassTable,
+ mappings,
+ this.subselect
+ );
+
+ if ( persistentClass instanceof TableOwner ) {
+ log.info( "Bind entity {} on table {}", persistentClass.getEntityName(),
table.getName() );
+ ( (TableOwner) persistentClass ).setTable( table );
+ }
+ else {
+ throw new AssertionFailure( "binding a table for a subclass" );
+ }
+ }
+
+ public void finalSecondaryTableBinding(PropertyHolder propertyHolder) {
+ /*
+ * Those operations has to be done after the id definition of the persistence class.
+ * ie after the properties parsing
+ */
+ Iterator joins = secondaryTables.values().iterator();
+ Iterator joinColumns = secondaryTableJoins.values().iterator();
+
+ while ( joins.hasNext() ) {
+ Object uncastedColumn = joinColumns.next();
+ Join join = (Join) joins.next();
+ createPrimaryColumnsToSecondaryTable( uncastedColumn, propertyHolder, join );
+ }
+ mappings.addJoins( persistentClass, secondaryTables );
+ }
+
+ private void createPrimaryColumnsToSecondaryTable(Object uncastedColumn, PropertyHolder
propertyHolder, Join join) {
+ Ejb3JoinColumn[] ejb3JoinColumns;
+ PrimaryKeyJoinColumn[] pkColumnsAnn = null;
+ JoinColumn[] joinColumnsAnn = null;
+ if ( uncastedColumn instanceof PrimaryKeyJoinColumn[] ) {
+ pkColumnsAnn = (PrimaryKeyJoinColumn[]) uncastedColumn;
+ }
+ if ( uncastedColumn instanceof JoinColumn[] ) {
+ joinColumnsAnn = (JoinColumn[]) uncastedColumn;
+ }
+ if ( pkColumnsAnn == null && joinColumnsAnn == null ) {
+ ejb3JoinColumns = new Ejb3JoinColumn[1];
+ ejb3JoinColumns[0] = Ejb3JoinColumn.buildJoinColumn(
+ null,
+ null,
+ persistentClass.getIdentifier(),
+ secondaryTables,
+ propertyHolder, mappings
+ );
+ }
+ else {
+ int nbrOfJoinColumns = pkColumnsAnn != null ?
+ pkColumnsAnn.length :
+ joinColumnsAnn.length;
+ if ( nbrOfJoinColumns == 0 ) {
+ ejb3JoinColumns = new Ejb3JoinColumn[1];
+ ejb3JoinColumns[0] = Ejb3JoinColumn.buildJoinColumn(
+ null,
+ null,
+ persistentClass.getIdentifier(),
+ secondaryTables,
+ propertyHolder, mappings
+ );
+ }
+ else {
+ ejb3JoinColumns = new Ejb3JoinColumn[nbrOfJoinColumns];
+ if ( pkColumnsAnn != null ) {
+ for (int colIndex = 0; colIndex < nbrOfJoinColumns; colIndex++) {
+ ejb3JoinColumns[colIndex] = Ejb3JoinColumn.buildJoinColumn(
+ pkColumnsAnn[colIndex],
+ null,
+ persistentClass.getIdentifier(),
+ secondaryTables,
+ propertyHolder, mappings
+ );
+ }
+ }
+ else {
+ for (int colIndex = 0; colIndex < nbrOfJoinColumns; colIndex++) {
+ ejb3JoinColumns[colIndex] = Ejb3JoinColumn.buildJoinColumn(
+ null,
+ joinColumnsAnn[colIndex],
+ persistentClass.getIdentifier(),
+ secondaryTables,
+ propertyHolder, mappings
+ );
+ }
+ }
+ }
+ }
+
+ for (Ejb3JoinColumn joinColumn : ejb3JoinColumns) {
+ joinColumn.forceNotNull();
+ }
+ bindJoinToPersistentClass( join, ejb3JoinColumns, mappings );
+ }
+
+ private void bindJoinToPersistentClass(Join join, Ejb3JoinColumn[] ejb3JoinColumns,
ExtendedMappings mappings) {
+ SimpleValue key = new DependantValue( mappings, join.getTable(),
persistentClass.getIdentifier() );
+ join.setKey( key );
+ setFKNameIfDefined( join );
+ key.setCascadeDeleteEnabled( false );
+ TableBinder.bindFk( persistentClass, null, ejb3JoinColumns, key, false, mappings );
+ join.createPrimaryKey();
+ join.createForeignKey();
+ persistentClass.addJoin( join );
+ }
+
+ private void setFKNameIfDefined(Join join) {
+ org.hibernate.annotations.Table matchingTable = findMatchingComplimentTableAnnotation(
join );
+ if ( matchingTable != null && !BinderHelper.isDefault(
matchingTable.foreignKey().name() ) ) {
+ ( (SimpleValue) join.getKey() ).setForeignKeyName( matchingTable.foreignKey().name()
);
+ }
+ }
+
+ private org.hibernate.annotations.Table findMatchingComplimentTableAnnotation(Join join)
{
+ String tableName = join.getTable().getQuotedName();
+ org.hibernate.annotations.Table table = annotatedClass.getAnnotation(
org.hibernate.annotations.Table.class );
+ org.hibernate.annotations.Table matchingTable = null;
+ if ( table != null && tableName.equals( table.appliesTo() ) ) {
+ matchingTable = table;
+ }
+ else {
+ Tables tables = annotatedClass.getAnnotation( Tables.class );
+ if ( tables != null ) {
+ for (org.hibernate.annotations.Table current : tables.value()) {
+ if ( tableName.equals( current.appliesTo() ) ) {
+ matchingTable = current;
+ break;
+ }
+ }
+ }
+ }
+ return matchingTable;
+ }
+
+ public void firstLevelSecondaryTablesBinding(
+ SecondaryTable secTable, SecondaryTables secTables
+ ) {
+ if ( secTables != null ) {
+ //loop through it
+ for (SecondaryTable tab : secTables.value()) {
+ addJoin( tab, null, null, false );
+ }
+ }
+ else {
+ if ( secTable != null ) addJoin( secTable, null, null, false );
+ }
+ }
+
+ //Used for @*ToMany @JoinTable
+ public Join addJoin(JoinTable joinTable, PropertyHolder holder, boolean
noDelayInPkColumnCreation) {
+ return addJoin( null, joinTable, holder, noDelayInPkColumnCreation );
+ }
+
+ private static class SecondaryTableNameSource implements ObjectNameSource {
+ // always has an explicit name
+ private final String explicitName;
+
+ private SecondaryTableNameSource(String explicitName) {
+ this.explicitName = explicitName;
+ }
+
+ public String getExplicitName() {
+ return explicitName;
+ }
+
+ public String getLogicalName() {
+ return explicitName;
+ }
+ }
+
+ private static class SecondaryTableNamingStrategyHelper implements
ObjectNameNormalizer.NamingStrategyHelper {
+ public String determineImplicitName(NamingStrategy strategy) {
+ // todo : throw an error?
+ return null;
+ }
+
+ public String handleExplicitName(NamingStrategy strategy, String name) {
+ return strategy.tableName( name );
+ }
+ }
+
+ private static SecondaryTableNamingStrategyHelper SEC_TBL_NS_HELPER = new
SecondaryTableNamingStrategyHelper();
+
+ private Join addJoin(
+ SecondaryTable secondaryTable,
+ JoinTable joinTable,
+ PropertyHolder propertyHolder,
+ boolean noDelayInPkColumnCreation) {
+ // A non null propertyHolder means than we process the Pk creation without delay
+ Join join = new Join();
+ join.setPersistentClass( persistentClass );
+
+ final String schema;
+ final String catalog;
+ final SecondaryTableNameSource secondaryTableNameContext;
+ final Object joinColumns;
+ final List<UniqueConstraintHolder> uniqueConstraintHolders;
+
+ if ( secondaryTable != null ) {
+ schema = secondaryTable.schema();
+ catalog = secondaryTable.catalog();
+ secondaryTableNameContext = new SecondaryTableNameSource( secondaryTable.name() );
+ joinColumns = secondaryTable.pkJoinColumns();
+ uniqueConstraintHolders = TableBinder.buildUniqueConstraintHolders(
secondaryTable.uniqueConstraints() );
+ }
+ else if ( joinTable != null ) {
+ schema = joinTable.schema();
+ catalog = joinTable.catalog();
+ secondaryTableNameContext = new SecondaryTableNameSource( joinTable.name() );
+ joinColumns = joinTable.joinColumns();
+ uniqueConstraintHolders = TableBinder.buildUniqueConstraintHolders(
joinTable.uniqueConstraints() );
+ }
+ else {
+ throw new AssertionFailure( "Both JoinTable and SecondaryTable are null" );
+ }
+
+ final Table table = TableBinder.buildAndFillTable(
+ schema,
+ catalog,
+ secondaryTableNameContext,
+ SEC_TBL_NS_HELPER,
+ false,
+ uniqueConstraintHolders,
+ null,
+ null,
+ mappings,
+ null
+ );
+
+ //no check constraints available on joins
+ join.setTable( table );
+
+ //somehow keep joins() for later.
+ //Has to do the work later because it needs persistentClass id!
+ log.info(
+ "Adding secondary table to entity {} -> {}",
persistentClass.getEntityName(), join.getTable().getName()
+ );
+ org.hibernate.annotations.Table matchingTable = findMatchingComplimentTableAnnotation(
join );
+ if ( matchingTable != null ) {
+ join.setSequentialSelect( FetchMode.JOIN != matchingTable.fetch() );
+ join.setInverse( matchingTable.inverse() );
+ join.setOptional( matchingTable.optional() );
+ if ( !BinderHelper.isDefault( matchingTable.sqlInsert().sql() ) ) {
+ join.setCustomSQLInsert( matchingTable.sqlInsert().sql().trim(),
+ matchingTable.sqlInsert().callable(),
+ ExecuteUpdateResultCheckStyle.parse(
matchingTable.sqlInsert().check().toString().toLowerCase() )
+ );
+ }
+ if ( !BinderHelper.isDefault( matchingTable.sqlUpdate().sql() ) ) {
+ join.setCustomSQLUpdate( matchingTable.sqlUpdate().sql().trim(),
+ matchingTable.sqlUpdate().callable(),
+ ExecuteUpdateResultCheckStyle.parse(
matchingTable.sqlUpdate().check().toString().toLowerCase() )
+ );
+ }
+ if ( !BinderHelper.isDefault( matchingTable.sqlDelete().sql() ) ) {
+ join.setCustomSQLDelete( matchingTable.sqlDelete().sql().trim(),
+ matchingTable.sqlDelete().callable(),
+ ExecuteUpdateResultCheckStyle.parse(
matchingTable.sqlDelete().check().toString().toLowerCase() )
+ );
+ }
+ }
+ else {
+ //default
+ join.setSequentialSelect( false );
+ join.setInverse( false );
+ join.setOptional( true ); //perhaps not quite per-spec, but a Good Thing anyway
+ }
+
+ if ( noDelayInPkColumnCreation ) {
+ createPrimaryColumnsToSecondaryTable( joinColumns, propertyHolder, join );
+ }
+ else {
+ secondaryTables.put( table.getQuotedName(), join );
+ secondaryTableJoins.put( table.getQuotedName(), joinColumns );
+ }
+ return join;
+ }
+
+ public java.util.Map<String, Join> getSecondaryTables() {
+ return secondaryTables;
+ }
+
+ public void setCache(Cache cacheAnn) {
+ if ( cacheAnn != null ) {
+ cacheRegion = BinderHelper.isDefault( cacheAnn.region() ) ?
+ null :
+ cacheAnn.region();
+ cacheConcurrentStrategy = getCacheConcurrencyStrategy( cacheAnn.usage() );
+ if ( "all".equalsIgnoreCase( cacheAnn.include() ) ) {
+ cacheLazyProperty = true;
+ }
+ else if ( "non-lazy".equalsIgnoreCase( cacheAnn.include() ) ) {
+ cacheLazyProperty = false;
+ }
+ else {
+ throw new AnnotationException( "Unknown lazy property annotations: " +
cacheAnn.include() );
+ }
+ }
+ else {
+ cacheConcurrentStrategy = null;
+ cacheRegion = null;
+ cacheLazyProperty = true;
+ }
+ }
+
+ public static String getCacheConcurrencyStrategy(CacheConcurrencyStrategy strategy) {
+ org.hibernate.cache.access.AccessType accessType = strategy.toAccessType();
+ return accessType == null ? null : accessType.getName();
+ }
+
+ public void addFilter(String name, String condition) {
+ filters.put( name, condition );
+ }
+
+ public void setInheritanceState(InheritanceState inheritanceState) {
+ this.inheritanceState = inheritanceState;
+ }
+
+ public boolean isIgnoreIdAnnotations() {
+ return ignoreIdAnnotations;
+ }
+
+ public void setIgnoreIdAnnotations(boolean ignoreIdAnnotations) {
+ this.ignoreIdAnnotations = ignoreIdAnnotations;
+ }
+
+ public void processComplementaryTableDefinitions(org.hibernate.annotations.Table table)
{
+ //comment and index are processed here
+ if ( table == null ) return;
+ String appliedTable = table.appliesTo();
+ Iterator tables = persistentClass.getTableClosureIterator();
+ Table hibTable = null;
+ while ( tables.hasNext() ) {
+ Table pcTable = (Table) tables.next();
+ if ( pcTable.getQuotedName().equals( appliedTable ) ) {
+ //we are in the correct table to find columns
+ hibTable = pcTable;
+ break;
+ }
+ hibTable = null;
+ }
+ if ( hibTable == null ) {
+ //maybe a join/secondary table
+ for ( Join join : secondaryTables.values() ) {
+ if ( join.getTable().getQuotedName().equals( appliedTable ) ) {
+ hibTable = join.getTable();
+ break;
+ }
+ }
+ }
+ if ( hibTable == null ) {
+ throw new AnnotationException(
+ "(a)org.hibernate.annotations.Table references an unknown table: " +
appliedTable
+ );
+ }
+ if ( !BinderHelper.isDefault( table.comment() ) ) hibTable.setComment( table.comment()
);
+ TableBinder.addIndexes( hibTable, table.indexes(), mappings );
+ }
+
+ public void processComplementaryTableDefinitions(Tables tables) {
+ if ( tables == null ) return;
+ for (org.hibernate.annotations.Table table : tables.value()) {
+ processComplementaryTableDefinitions( table );
+ }
+ }
+
+ public AccessType getPropertyAccessType() {
+ return propertyAccessType;
+ }
+
+ public void setPropertyAccessType(AccessType propertyAccessor) {
+ this.propertyAccessType = getExplicitAccessType( annotatedClass );
+ // only set the access type if there is no explicit access type for this class
+ if( this.propertyAccessType == null ) {
+ this.propertyAccessType = propertyAccessor;
+ }
+ }
+
+ public AccessType getPropertyAccessor(XAnnotatedElement element) {
+ AccessType accessType = getExplicitAccessType( element );
+ if ( accessType == null ) {
+ accessType = propertyAccessType;
+ }
+ return accessType;
+ }
+
+ public AccessType getExplicitAccessType(XAnnotatedElement element) {
+ AccessType accessType = null;
+
+ AccessType hibernateAccessType = null;
+ AccessType jpaAccessType = null;
+
+ org.hibernate.annotations.AccessType accessTypeAnnotation = element.getAnnotation(
org.hibernate.annotations.AccessType.class );
+ if ( accessTypeAnnotation != null ) {
+ hibernateAccessType = AccessType.getAccessStrategy( accessTypeAnnotation.value() );
+ }
+
+ Access access = element.getAnnotation( Access.class );
+ if ( access != null ) {
+ jpaAccessType = AccessType.getAccessStrategy( access.value() );
+ }
+
+ if ( hibernateAccessType != null && jpaAccessType != null &&
hibernateAccessType != jpaAccessType ) {
+ throw new MappingException(
+ "Found @Access and @AccessType with conflicting values on a property in class
" + annotatedClass.toString()
+ );
+ }
+
+ if ( hibernateAccessType != null ) {
+ accessType = hibernateAccessType;
+ }
+ else if ( jpaAccessType != null ) {
+ accessType = jpaAccessType;
+ }
+
+ return accessType;
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/annotations/IdBagBinder.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/IdBagBinder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/annotations/IdBagBinder.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/IdBagBinder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,115 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg.annotations;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.annotations.CollectionId;
+import org.hibernate.annotations.Type;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.cfg.BinderHelper;
+import org.hibernate.cfg.Ejb3Column;
+import org.hibernate.cfg.Ejb3JoinColumn;
+import org.hibernate.cfg.ExtendedMappings;
+import org.hibernate.cfg.PropertyData;
+import org.hibernate.cfg.PropertyInferredData;
+import org.hibernate.cfg.WrappedInferredData;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.IdentifierCollection;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.SimpleValue;
+import org.hibernate.mapping.Table;
+import org.hibernate.util.StringHelper;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class IdBagBinder extends BagBinder {
+ protected Collection createCollection(PersistentClass persistentClass) {
+ return new org.hibernate.mapping.IdentifierBag( getMappings(), persistentClass );
+ }
+
+ @Override
+ protected boolean bindStarToManySecondPass(
+ Map persistentClasses, XClass collType, Ejb3JoinColumn[] fkJoinColumns,
Ejb3JoinColumn[] keyColumns,
+ Ejb3JoinColumn[] inverseColumns, Ejb3Column[] elementColumns, boolean isEmbedded,
XProperty property,
+ boolean unique, TableBinder associationTableBinder, boolean ignoreNotFound,
ExtendedMappings mappings
+ ) {
+ boolean result = super.bindStarToManySecondPass(
+ persistentClasses, collType, fkJoinColumns, keyColumns, inverseColumns,
elementColumns, isEmbedded,
+ property, unique, associationTableBinder, ignoreNotFound, mappings
+ );
+ CollectionId collectionIdAnn = property.getAnnotation( CollectionId.class );
+ if ( collectionIdAnn != null ) {
+ SimpleValueBinder simpleValue = new SimpleValueBinder();
+
+ PropertyData propertyData = new WrappedInferredData(
+ new PropertyInferredData( null, property, null, //default access should not be
useful
+ mappings.getReflectionManager() ),
+ "id" );
+ Ejb3Column[] idColumns = Ejb3Column.buildColumnFromAnnotation(
+ collectionIdAnn.columns(),
+ null,
+ Nullability.FORCED_NOT_NULL,
+ propertyHolder,
+ propertyData,
+ Collections.EMPTY_MAP,
+ mappings
+ );
+ //we need to make sure all id columns must be not-null.
+ for(Ejb3Column idColumn:idColumns){
+ idColumn.setNullable(false);
+ }
+ Table table = collection.getCollectionTable();
+ simpleValue.setTable( table );
+ simpleValue.setColumns( idColumns );
+ Type typeAnn = collectionIdAnn.type();
+ if ( typeAnn != null && !BinderHelper.isDefault( typeAnn.type() ) ) {
+ simpleValue.setExplicitType( typeAnn );
+ }
+ else {
+ throw new AnnotationException( "@CollectionId is missing type: "
+ + StringHelper.qualify( propertyHolder.getPath(), propertyName ) );
+ }
+ simpleValue.setMappings( mappings );
+ SimpleValue id = simpleValue.make();
+ ( (IdentifierCollection) collection ).setIdentifier( id );
+ String generator = collectionIdAnn.generator();
+ String generatorType;
+ if ( "identity".equals( generator ) || "assigned".equals(
generator )
+ || "sequence".equals( generator ) || "native".equals( generator
) ) {
+ generatorType = generator;
+ generator = "";
+ }
+ else {
+ generatorType = null;
+ }
+ BinderHelper.makeIdGenerator( id, generatorType, generator, mappings, localGenerators
);
+ }
+ return result;
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/IdBagBinder.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/annotations/ListBinder.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/ListBinder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/annotations/ListBinder.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/annotations/ListBinder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,139 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg.annotations;
+
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.MappingException;
+import org.hibernate.annotations.OrderBy;
+import org.hibernate.annotations.Sort;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.cfg.CollectionSecondPass;
+import org.hibernate.cfg.Ejb3Column;
+import org.hibernate.cfg.Ejb3JoinColumn;
+import org.hibernate.cfg.ExtendedMappings;
+import org.hibernate.cfg.PropertyHolder;
+import org.hibernate.cfg.PropertyHolderBuilder;
+import org.hibernate.cfg.SecondPass;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.IndexBackref;
+import org.hibernate.mapping.List;
+import org.hibernate.mapping.OneToMany;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.SimpleValue;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Bind a list to the underlying Hibernate configuration
+ *
+ * @author Matthew Inger
+ * @author Emmanuel Bernard
+ */
+@SuppressWarnings({"unchecked", "serial"})
+public class ListBinder extends CollectionBinder {
+ private Logger log = LoggerFactory.getLogger( ListBinder.class );
+
+ public ListBinder() {
+ }
+
+ protected Collection createCollection(PersistentClass persistentClass) {
+ return new org.hibernate.mapping.List( getMappings(), persistentClass );
+ }
+
+ public void setSqlOrderBy(OrderBy orderByAnn) {
+ if ( orderByAnn != null ) log.warn( "@OrderBy not allowed for a indexed
collection, annotation ignored." );
+ }
+
+ public void setSort(Sort sortAnn) {
+ if ( sortAnn != null ) log.warn( "@Sort not allowed for a indexed collection,
annotation ignored." );
+ }
+
+ @Override
+ public SecondPass getSecondPass(
+ final Ejb3JoinColumn[] fkJoinColumns, final Ejb3JoinColumn[] keyColumns,
+ final Ejb3JoinColumn[] inverseColumns,
+ final Ejb3Column[] elementColumns,
+ Ejb3Column[] mapKeyColumns, final Ejb3JoinColumn[] mapKeyManyToManyColumns, final
boolean isEmbedded,
+ final XProperty property, final XClass collType,
+ final boolean ignoreNotFound, final boolean unique,
+ final TableBinder assocTableBinder, final ExtendedMappings mappings
+ ) {
+ return new CollectionSecondPass( mappings, ListBinder.this.collection ) {
+ public void secondPass(Map persistentClasses, Map inheritedMetas)
+ throws MappingException {
+ bindStarToManySecondPass(
+ persistentClasses, collType, fkJoinColumns, keyColumns, inverseColumns,
elementColumns,
+ isEmbedded, property, unique, assocTableBinder, ignoreNotFound, mappings
+ );
+ bindIndex( mappings );
+ }
+ };
+ }
+
+ private void bindIndex(final ExtendedMappings mappings) {
+ if ( !indexColumn.isImplicit() ) {
+ PropertyHolder valueHolder = PropertyHolderBuilder.buildPropertyHolder(
+ this.collection,
+ StringHelper.qualify( this.collection.getRole(), "key" ),
+ (XClass) null,
+ (XProperty) null, propertyHolder, mappings
+ );
+ List list = (List) this.collection;
+ if ( !list.isOneToMany() ) indexColumn.forceNotNull();
+ indexColumn.setPropertyHolder( valueHolder );
+ SimpleValueBinder value = new SimpleValueBinder();
+ value.setColumns( new Ejb3Column[] { indexColumn } );
+ value.setExplicitType( "integer" );
+ value.setMappings( mappings );
+ SimpleValue indexValue = value.make();
+ indexColumn.linkWithValue( indexValue );
+ list.setIndex( indexValue );
+ list.setBaseIndex( indexColumn.getBase() );
+ if ( list.isOneToMany() && !list.getKey().isNullable() &&
!list.isInverse() ) {
+ String entityName = ( (OneToMany) list.getElement() ).getReferencedEntityName();
+ PersistentClass referenced = mappings.getClass( entityName );
+ IndexBackref ib = new IndexBackref();
+ ib.setName( '_' + propertyName + "IndexBackref" );
+ ib.setUpdateable( false );
+ ib.setSelectable( false );
+ ib.setCollectionRole( list.getRole() );
+ ib.setEntityName( list.getOwner().getEntityName() );
+ ib.setValue( list.getIndex() );
+ referenced.addProperty( ib );
+ }
+ }
+ else {
+ Collection coll = this.collection;
+ throw new AnnotationException(
+ "List/array has to be annotated with an @OrderColumn (or @IndexColumn): "
+ + coll.getRole()
+ );
+ }
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/ListBinder.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/annotations/MapBinder.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/MapBinder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/annotations/MapBinder.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/annotations/MapBinder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,432 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg.annotations;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Random;
+import javax.persistence.AttributeOverride;
+import javax.persistence.AttributeOverrides;
+import javax.persistence.MapKeyClass;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.AssertionFailure;
+import org.hibernate.FetchMode;
+import org.hibernate.MappingException;
+import org.hibernate.annotations.MapKey;
+import org.hibernate.annotations.MapKeyManyToMany;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.cfg.AccessType;
+import org.hibernate.cfg.AnnotatedClassType;
+import org.hibernate.cfg.AnnotationBinder;
+import org.hibernate.cfg.BinderHelper;
+import org.hibernate.cfg.CollectionSecondPass;
+import org.hibernate.cfg.Ejb3Column;
+import org.hibernate.cfg.Ejb3JoinColumn;
+import org.hibernate.cfg.ExtendedMappings;
+import org.hibernate.cfg.PropertyData;
+import org.hibernate.cfg.PropertyHolder;
+import org.hibernate.cfg.PropertyHolderBuilder;
+import org.hibernate.cfg.PropertyPreloadedData;
+import org.hibernate.cfg.SecondPass;
+import org.hibernate.dialect.HSQLDialect;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.DependantValue;
+import org.hibernate.mapping.Formula;
+import org.hibernate.mapping.Join;
+import org.hibernate.mapping.ManyToOne;
+import org.hibernate.mapping.OneToMany;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.SimpleValue;
+import org.hibernate.mapping.ToOne;
+import org.hibernate.mapping.Value;
+import org.hibernate.sql.Template;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Implementation to bind a Map
+ *
+ * @author Emmanuel Bernard
+ */
+public class MapBinder extends CollectionBinder {
+ public MapBinder(boolean sorted) {
+ super( sorted );
+ }
+
+ public MapBinder() {
+ super();
+ }
+
+ public boolean isMap() {
+ return true;
+ }
+
+ protected Collection createCollection(PersistentClass persistentClass) {
+ return new org.hibernate.mapping.Map( getMappings(), persistentClass );
+ }
+
+ @Override
+ public SecondPass getSecondPass(
+ final Ejb3JoinColumn[] fkJoinColumns, final Ejb3JoinColumn[] keyColumns,
+ final Ejb3JoinColumn[] inverseColumns,
+ final Ejb3Column[] elementColumns,
+ final Ejb3Column[] mapKeyColumns, final Ejb3JoinColumn[] mapKeyManyToManyColumns,
final boolean isEmbedded,
+ final XProperty property, final XClass collType,
+ final boolean ignoreNotFound, final boolean unique,
+ final TableBinder assocTableBinder, final ExtendedMappings mappings
+ ) {
+ return new CollectionSecondPass( mappings, MapBinder.this.collection ) {
+ public void secondPass(Map persistentClasses, Map inheritedMetas)
+ throws MappingException {
+ bindStarToManySecondPass(
+ persistentClasses, collType, fkJoinColumns, keyColumns, inverseColumns,
elementColumns,
+ isEmbedded, property, unique, assocTableBinder, ignoreNotFound, mappings
+ );
+ bindKeyFromAssociationTable(
+ collType, persistentClasses, mapKeyPropertyName, property, isEmbedded, mappings,
+ mapKeyColumns, mapKeyManyToManyColumns,
+ inverseColumns != null ? inverseColumns[0].getPropertyName() : null
+ );
+ }
+ };
+ }
+
+ private void bindKeyFromAssociationTable(
+ XClass collType, Map persistentClasses, String mapKeyPropertyName, XProperty
property,
+ boolean isEmbedded, ExtendedMappings mappings, Ejb3Column[] mapKeyColumns,
+ Ejb3JoinColumn[] mapKeyManyToManyColumns, String targetPropertyName
+ ) {
+ if ( mapKeyPropertyName != null ) {
+ //this is an EJB3 @MapKey
+ PersistentClass associatedClass = (PersistentClass) persistentClasses.get(
collType.getName() );
+ if ( associatedClass == null ) throw new AnnotationException( "Associated class
not found: " + collType );
+ Property mapProperty = BinderHelper.findPropertyByName( associatedClass,
mapKeyPropertyName );
+ if ( mapProperty == null ) {
+ throw new AnnotationException(
+ "Map key property not found: " + collType + "." +
mapKeyPropertyName
+ );
+ }
+ org.hibernate.mapping.Map map = (org.hibernate.mapping.Map) this.collection;
+ Value indexValue = createFormulatedValue( mapProperty.getValue(), map,
targetPropertyName, associatedClass, mappings );
+ map.setIndex( indexValue );
+ }
+ else {
+ //this is a true Map mapping
+ //TODO ugly copy/pastle from CollectionBinder.bindManyToManySecondPass
+ String mapKeyType;
+ Class target = void.class;
+ /*
+ * target has priority over reflection for the map key type
+ * JPA 2 has priority
+ */
+ if ( property.isAnnotationPresent( MapKeyClass.class ) ) {
+ target = property.getAnnotation( MapKeyClass.class ).value();
+ }
+ else if ( property.isAnnotationPresent( org.hibernate.annotations.MapKey.class ) ) {
+ target = property.getAnnotation( org.hibernate.annotations.MapKey.class
).targetElement();
+ }
+ else if ( property.isAnnotationPresent( MapKeyManyToMany.class ) ) {
+ target = property.getAnnotation( MapKeyManyToMany.class ).targetEntity();
+ }
+ if ( !void.class.equals( target ) ) {
+ mapKeyType = target.getName();
+ }
+ else {
+ mapKeyType = property.getMapKey().getName();
+ }
+ PersistentClass collectionEntity = (PersistentClass) persistentClasses.get( mapKeyType
);
+ boolean isIndexOfEntities = collectionEntity != null;
+ ManyToOne element = null;
+ org.hibernate.mapping.Map mapValue = (org.hibernate.mapping.Map) this.collection;
+ if ( isIndexOfEntities ) {
+ element = new ManyToOne( mappings, mapValue.getCollectionTable() );
+ mapValue.setIndex( element );
+ element.setReferencedEntityName( mapKeyType );
+ //element.setFetchMode( fetchMode );
+ //element.setLazy( fetchMode != FetchMode.JOIN );
+ //make the second join non lazy
+ element.setFetchMode( FetchMode.JOIN );
+ element.setLazy( false );
+ //does not make sense for a map key element.setIgnoreNotFound( ignoreNotFound );
+ }
+ else {
+ XClass elementClass;
+ AnnotatedClassType classType;
+ PropertyHolder holder = null;
+ if ( BinderHelper.PRIMITIVE_NAMES.contains( mapKeyType ) ) {
+ classType = AnnotatedClassType.NONE;
+ elementClass = null;
+ }
+ else {
+ try {
+ elementClass = mappings.getReflectionManager().classForName( mapKeyType,
MapBinder.class );
+ }
+ catch (ClassNotFoundException e) {
+ throw new AnnotationException( "Unable to find class: " + mapKeyType, e
);
+ }
+ classType = mappings.getClassType( elementClass );
+
+ holder = PropertyHolderBuilder.buildPropertyHolder(
+ mapValue,
+ StringHelper.qualify( mapValue.getRole(), "mapkey" ),
+ elementClass,
+ property, propertyHolder, mappings
+ );
+ //force in case of attribute override
+ boolean attributeOverride = property.isAnnotationPresent( AttributeOverride.class )
+ || property.isAnnotationPresent( AttributeOverrides.class );
+ if ( isEmbedded || attributeOverride ) {
+ classType = AnnotatedClassType.EMBEDDABLE;
+ }
+ }
+
+ if ( AnnotatedClassType.EMBEDDABLE.equals( classType ) ) {
+ EntityBinder entityBinder = new EntityBinder();
+ PersistentClass owner = mapValue.getOwner();
+ boolean isPropertyAnnotated;
+ //FIXME support @Access for collection of elements
+ //String accessType = access != null ? access.value() : null;
+ if ( owner.getIdentifierProperty() != null ) {
+ isPropertyAnnotated = owner.getIdentifierProperty()
+ .getPropertyAccessorName()
+ .equals( "property" );
+ }
+ else
+ if ( owner.getIdentifierMapper() != null &&
owner.getIdentifierMapper().getPropertySpan() > 0 ) {
+ Property prop = (Property)
owner.getIdentifierMapper().getPropertyIterator().next();
+ isPropertyAnnotated = prop.getPropertyAccessorName().equals( "property"
);
+ }
+ else {
+ throw new AssertionFailure( "Unable to guess collection property accessor
name" );
+ }
+
+
+ PropertyData inferredData;
+ if ( isHibernateExtensionMapping() ) {
+ inferredData = new PropertyPreloadedData( AccessType.PROPERTY, "index",
elementClass );
+ }
+ else {
+ //"key" is the JPA 2 prefix for map keys
+ inferredData = new PropertyPreloadedData( AccessType.PROPERTY, "key",
elementClass );
+ }
+
+ //TODO be smart with isNullable
+ Component component = AnnotationBinder.fillComponent(
+ holder, inferredData, isPropertyAnnotated ? AccessType.PROPERTY :
AccessType.FIELD, true,
+ entityBinder, false, false,
+ true, mappings, inheritanceStatePerClass
+ );
+ mapValue.setIndex( component );
+ }
+ else {
+ SimpleValueBinder elementBinder = new SimpleValueBinder();
+ elementBinder.setMappings( mappings );
+ elementBinder.setReturnedClassName( mapKeyType );
+
+ Ejb3Column[] elementColumns = mapKeyColumns;
+ if ( elementColumns == null || elementColumns.length == 0 ) {
+ elementColumns = new Ejb3Column[1];
+ Ejb3Column column = new Ejb3Column();
+ column.setImplicit( false );
+ column.setNullable( true );
+ column.setLength( Ejb3Column.DEFAULT_COLUMN_LENGTH );
+ column.setLogicalColumnName( Collection.DEFAULT_KEY_COLUMN_NAME );
+ //TODO create an EMPTY_JOINS collection
+ column.setJoins( new HashMap<String, Join>() );
+ column.setMappings( mappings );
+ column.bind();
+ elementColumns[0] = column;
+ }
+ //override the table
+ for (Ejb3Column column : elementColumns) {
+ column.setTable( mapValue.getCollectionTable() );
+ }
+ elementBinder.setColumns( elementColumns );
+ //do not call setType as it extract the type from @Type
+ //the algorithm generally does not apply for map key anyway
+ MapKey mapKeyAnn = property.getAnnotation( org.hibernate.annotations.MapKey.class
);
+ elementBinder.setKey(true);
+ if (mapKeyAnn != null && ! BinderHelper.isDefault( mapKeyAnn.type().type() )
) {
+ elementBinder.setExplicitType( mapKeyAnn.type() );
+ }
+ else {
+ elementBinder.setType( property, elementClass );
+ }
+ mapValue.setIndex( elementBinder.make() );
+ }
+ }
+ //FIXME pass the Index Entity JoinColumns
+ if ( !collection.isOneToMany() ) {
+ //index column shoud not be null
+ for (Ejb3JoinColumn col : mapKeyManyToManyColumns) {
+ col.forceNotNull();
+ }
+ }
+ if ( isIndexOfEntities ) {
+ bindManytoManyInverseFk(
+ collectionEntity,
+ mapKeyManyToManyColumns,
+ element,
+ false, //a map key column has no unique constraint
+ mappings
+ );
+ }
+ }
+ }
+
+ protected Value createFormulatedValue(
+ Value value,
+ Collection collection,
+ String targetPropertyName,
+ PersistentClass associatedClass,
+ ExtendedMappings mappings) {
+ Value element = collection.getElement();
+ String fromAndWhere = null;
+ if ( !( element instanceof OneToMany ) ) {
+ String referencedPropertyName = null;
+ if ( element instanceof ToOne ) {
+ referencedPropertyName = ( (ToOne) element ).getReferencedPropertyName();
+ }
+ else if ( element instanceof DependantValue ) {
+ //TODO this never happen I think
+ if ( propertyName != null ) {
+ referencedPropertyName = collection.getReferencedPropertyName();
+ }
+ else {
+ throw new AnnotationException( "SecondaryTable JoinColumn cannot reference a
non primary key" );
+ }
+ }
+ Iterator referencedEntityColumns;
+ if ( referencedPropertyName == null ) {
+ referencedEntityColumns = associatedClass.getIdentifier().getColumnIterator();
+ }
+ else {
+ Property referencedProperty = associatedClass.getRecursiveProperty(
referencedPropertyName );
+ referencedEntityColumns = referencedProperty.getColumnIterator();
+ }
+ String alias = "$alias$";
+ StringBuilder fromAndWhereSb = new StringBuilder( " from " )
+ .append( associatedClass.getTable().getName() )
+ //.append(" as ") //Oracle doesn't support it in subqueries
+ .append( " " )
+ .append( alias ).append( " where " );
+ Iterator collectionTableColumns = element.getColumnIterator();
+ while ( collectionTableColumns.hasNext() ) {
+ Column colColumn = (Column) collectionTableColumns.next();
+ Column refColumn = (Column) referencedEntityColumns.next();
+ fromAndWhereSb.append( alias ).append( '.' ).append(
refColumn.getQuotedName() )
+ .append( '=' ).append( colColumn.getQuotedName() ).append( " and
" );
+ }
+ fromAndWhere = fromAndWhereSb.substring( 0, fromAndWhereSb.length() - 5 );
+ }
+
+ if ( value instanceof Component ) {
+ Component component = (Component) value;
+ Iterator properties = component.getPropertyIterator();
+ Component indexComponent = new Component( mappings, collection );
+ indexComponent.setComponentClassName( component.getComponentClassName() );
+ //TODO I don't know if this is appropriate
+ indexComponent.setNodeName( "index" );
+ while ( properties.hasNext() ) {
+ Property current = (Property) properties.next();
+ Property newProperty = new Property();
+ newProperty.setCascade( current.getCascade() );
+ newProperty.setGeneration( current.getGeneration() );
+ newProperty.setInsertable( false );
+ newProperty.setUpdateable( false );
+ newProperty.setMetaAttributes( current.getMetaAttributes() );
+ newProperty.setName( current.getName() );
+ newProperty.setNodeName( current.getNodeName() );
+ newProperty.setNaturalIdentifier( false );
+ //newProperty.setOptimisticLocked( false );
+ newProperty.setOptional( false );
+ newProperty.setPersistentClass( current.getPersistentClass() );
+ newProperty.setPropertyAccessorName( current.getPropertyAccessorName() );
+ newProperty.setSelectable( current.isSelectable() );
+ newProperty.setValue(
+ createFormulatedValue(
+ current.getValue(), collection, targetPropertyName, associatedClass, mappings
+ )
+ );
+ indexComponent.addProperty( newProperty );
+ }
+ return indexComponent;
+ }
+ else if ( value instanceof SimpleValue ) {
+ SimpleValue sourceValue = (SimpleValue) value;
+ SimpleValue targetValue;
+ if ( value instanceof ManyToOne ) {
+ ManyToOne sourceManyToOne = (ManyToOne) sourceValue;
+ ManyToOne targetManyToOne = new ManyToOne( mappings, collection.getCollectionTable()
);
+ targetManyToOne.setFetchMode( FetchMode.DEFAULT );
+ targetManyToOne.setLazy( true );
+ //targetValue.setIgnoreNotFound( ); does not make sense for a map key
+ targetManyToOne.setReferencedEntityName( sourceManyToOne.getReferencedEntityName()
);
+ targetValue = targetManyToOne;
+ }
+ else {
+ targetValue = new SimpleValue( mappings, collection.getCollectionTable() );
+ targetValue.setTypeName( sourceValue.getTypeName() );
+ targetValue.setTypeParameters( sourceValue.getTypeParameters() );
+ }
+ Iterator columns = sourceValue.getColumnIterator();
+ Random random = new Random();
+ while ( columns.hasNext() ) {
+ Object current = columns.next();
+ Formula formula = new Formula();
+ String formulaString;
+ if ( current instanceof Column ) {
+ formulaString = ( (Column) current ).getQuotedName();
+ }
+ else if ( current instanceof Formula ) {
+ formulaString = ( (Formula) current ).getFormula();
+ }
+ else {
+ throw new AssertionFailure( "Unknown element in column iterator: " +
current.getClass() );
+ }
+ if ( fromAndWhere != null ) {
+ formulaString = Template.renderWhereStringTemplate( formulaString,
"$alias$", new HSQLDialect() );
+ formulaString = "(select " + formulaString + fromAndWhere +
")";
+ formulaString = StringHelper.replace(
+ formulaString,
+ "$alias$",
+ "a" + random.nextInt( 16 )
+ );
+ }
+ formula.setFormula( formulaString );
+ targetValue.addFormula( formula );
+
+ }
+ return targetValue;
+ }
+ else {
+ throw new AssertionFailure( "Unknown type encounters for map key: " +
value.getClass() );
+ }
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/MapBinder.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/MapKeyColumnDelegator.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/MapKeyColumnDelegator.java)
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/MapKeyColumnDelegator.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/MapKeyColumnDelegator.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,61 @@
+package org.hibernate.cfg.annotations;
+
+import java.lang.annotation.Annotation;
+import javax.persistence.Column;
+import javax.persistence.MapKeyColumn;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@SuppressWarnings({ "ClassExplicitlyAnnotation" })
+public class MapKeyColumnDelegator implements Column {
+ private final MapKeyColumn column;
+
+ public MapKeyColumnDelegator(MapKeyColumn column) {
+ this.column = column;
+ }
+
+ public String name() {
+ return column.name();
+ }
+
+ public boolean unique() {
+ return column.unique();
+ }
+
+ public boolean nullable() {
+ return column.nullable();
+ }
+
+ public boolean insertable() {
+ return column.insertable();
+ }
+
+ public boolean updatable() {
+ return column.updatable();
+ }
+
+ public String columnDefinition() {
+ return column.columnDefinition();
+ }
+
+ public String table() {
+ return column.table();
+ }
+
+ public int length() {
+ return column.length();
+ }
+
+ public int precision() {
+ return column.precision();
+ }
+
+ public int scale() {
+ return column.scale();
+ }
+
+ public Class<? extends Annotation> annotationType() {
+ return Column.class;
+ }
+}
Copied:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/MapKeyJoinColumnDelegator.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/MapKeyJoinColumnDelegator.java)
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/MapKeyJoinColumnDelegator.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/MapKeyJoinColumnDelegator.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,54 @@
+package org.hibernate.cfg.annotations;
+
+import java.lang.annotation.Annotation;
+import javax.persistence.Column;
+import javax.persistence.MapKeyJoinColumn;
+import javax.persistence.JoinColumn;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@SuppressWarnings({ "ClassExplicitlyAnnotation" })
+public class MapKeyJoinColumnDelegator implements JoinColumn {
+ private final MapKeyJoinColumn column;
+
+ public MapKeyJoinColumnDelegator(MapKeyJoinColumn column) {
+ this.column = column;
+ }
+
+ public String name() {
+ return column.name();
+ }
+
+ public String referencedColumnName() {
+ return column.referencedColumnName();
+ }
+
+ public boolean unique() {
+ return column.unique();
+ }
+
+ public boolean nullable() {
+ return column.nullable();
+ }
+
+ public boolean insertable() {
+ return column.insertable();
+ }
+
+ public boolean updatable() {
+ return column.updatable();
+ }
+
+ public String columnDefinition() {
+ return column.columnDefinition();
+ }
+
+ public String table() {
+ return column.table();
+ }
+
+ public Class<? extends Annotation> annotationType() {
+ return Column.class;
+ }
+}
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/annotations/Nullability.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/Nullability.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/annotations/Nullability.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/Nullability.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,35 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg.annotations;
+
+/**
+ * Are the columns forced to null, not null or not forced
+ *
+ * @author Emmanuel Bernard
+ */
+public enum Nullability {
+ FORCED_NULL,
+ FORCED_NOT_NULL,
+ NO_CONSTRAINT
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/Nullability.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/PrimitiveArrayBinder.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/PrimitiveArrayBinder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/annotations/PrimitiveArrayBinder.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/PrimitiveArrayBinder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,38 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg.annotations;
+
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.PrimitiveArray;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class PrimitiveArrayBinder extends ArrayBinder {
+ @Override
+ protected Collection createCollection(PersistentClass persistentClass) {
+ return new PrimitiveArray( getMappings(), persistentClass );
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/PrimitiveArrayBinder.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,339 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg.annotations;
+
+import java.util.Map;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Id;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.annotations.Generated;
+import org.hibernate.annotations.GenerationTime;
+import org.hibernate.annotations.Immutable;
+import org.hibernate.annotations.NaturalId;
+import org.hibernate.annotations.OptimisticLock;
+import org.hibernate.annotations.common.AssertionFailure;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.cfg.AccessType;
+import org.hibernate.cfg.AnnotationBinder;
+import org.hibernate.cfg.BinderHelper;
+import org.hibernate.cfg.Ejb3Column;
+import org.hibernate.cfg.ExtendedMappings;
+import org.hibernate.cfg.InheritanceState;
+import org.hibernate.cfg.PropertyHolder;
+import org.hibernate.cfg.PropertyPreloadedData;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.KeyValue;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.PropertyGeneration;
+import org.hibernate.mapping.RootClass;
+import org.hibernate.mapping.SimpleValue;
+import org.hibernate.mapping.Value;
+import org.hibernate.util.StringHelper;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class PropertyBinder {
+ private Logger log = LoggerFactory.getLogger( PropertyBinder.class );
+ private String name;
+ private String returnedClassName;
+ private boolean lazy;
+ private AccessType accessType;
+ private Ejb3Column[] columns;
+ private PropertyHolder holder;
+ private ExtendedMappings mappings;
+ private Value value;
+ private boolean insertable = true;
+ private boolean updatable = true;
+ private String cascade;
+ private SimpleValueBinder simpleValueBinder;
+ private XClass declaringClass;
+ private boolean declaringClassSet;
+ private boolean embedded;
+ private EntityBinder entityBinder;
+ private boolean isXToMany;
+ private String referencedEntityName;
+
+ public void setReferencedEntityName(String referencedEntityName) {
+ this.referencedEntityName = referencedEntityName;
+ }
+
+ public void setEmbedded(boolean embedded) {
+ this.embedded = embedded;
+ }
+
+ public void setEntityBinder(EntityBinder entityBinder) {
+ this.entityBinder = entityBinder;
+ }
+
+ /*
+ * property can be null
+ * prefer propertyName to property.getName() since some are overloaded
+ */
+ private XProperty property;
+ private XClass returnedClass;
+ private boolean isId;
+ private Map<XClass, InheritanceState> inheritanceStatePerClass;
+ private Property mappingProperty;
+
+ public void setInsertable(boolean insertable) {
+ this.insertable = insertable;
+ }
+
+ public void setUpdatable(boolean updatable) {
+ this.updatable = updatable;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setReturnedClassName(String returnedClassName) {
+ this.returnedClassName = returnedClassName;
+ }
+
+ public void setLazy(boolean lazy) {
+ this.lazy = lazy;
+ }
+
+ public void setAccessType(AccessType accessType) {
+ this.accessType = accessType;
+ }
+
+ public void setColumns(Ejb3Column[] columns) {
+ insertable = columns[0].isInsertable();
+ updatable = columns[0].isUpdatable();
+ //consistency is checked later when we know the property name
+ this.columns = columns;
+ }
+
+ public void setHolder(PropertyHolder holder) {
+ this.holder = holder;
+ }
+
+ public void setValue(Value value) {
+ this.value = value;
+ }
+
+ public void setCascade(String cascadeStrategy) {
+ this.cascade = cascadeStrategy;
+ }
+
+ public void setMappings(ExtendedMappings mappings) {
+ this.mappings = mappings;
+ }
+
+ public void setDeclaringClass(XClass declaringClass) {
+ this.declaringClass = declaringClass;
+ this.declaringClassSet = true;
+ }
+
+ private void validateBind() {
+ if ( property.isAnnotationPresent( Immutable.class ) ) {
+ throw new AnnotationException(
+ "@Immutable on property not allowed. " +
+ "Only allowed on entity level or on a collection."
+ );
+ }
+ if ( !declaringClassSet ) {
+ throw new AssertionFailure( "declaringClass has not been set before a bind"
);
+ }
+ }
+
+ private void validateMake() {
+ //TODO check necessary params for a make
+ }
+
+ private Property makePropertyAndValue() {
+ validateBind();
+ log.debug( "binding property {} with lazy={}", name, lazy );
+ String containerClassName = holder == null ?
+ null :
+ holder.getClassName();
+ simpleValueBinder = new SimpleValueBinder();
+ simpleValueBinder.setMappings( mappings );
+ simpleValueBinder.setPropertyName( name );
+ simpleValueBinder.setReturnedClassName( returnedClassName );
+ simpleValueBinder.setColumns( columns );
+ simpleValueBinder.setPersistentClassName( containerClassName );
+ simpleValueBinder.setType( property, returnedClass );
+ simpleValueBinder.setMappings( mappings );
+ simpleValueBinder.setReferencedEntityName( referencedEntityName );
+ SimpleValue propertyValue = simpleValueBinder.make();
+ setValue( propertyValue );
+ return makeProperty();
+ }
+
+ //used when value is provided
+ public Property makePropertyAndBind() {
+ return bind( makeProperty() );
+ }
+
+ //used to build everything from scratch
+ public Property makePropertyValueAndBind() {
+ return bind( makePropertyAndValue() );
+ }
+
+ public void setXToMany(boolean xToMany) {
+ this.isXToMany = xToMany;
+ }
+
+ private Property bind(Property prop) {
+ if (isId) {
+ final RootClass rootClass = ( RootClass ) holder.getPersistentClass();
+ //if an xToMany, it as to be wrapped today.
+ //FIXME this pose a problem as the PK is the class instead of the associated class
which is not really compliant with the spec
+ if ( isXToMany || entityBinder.wrapIdsInEmbeddedComponents() ) {
+ Component identifier = (Component) rootClass.getIdentifier();
+ if (identifier == null) {
+ identifier = AnnotationBinder.createComponent( holder, new
PropertyPreloadedData(null, null, null), true, false, mappings );
+ rootClass.setIdentifier( identifier );
+ identifier.setNullValue( "undefined" );
+ rootClass.setEmbeddedIdentifier( true );
+ }
+ //FIXME is it good enough?
+ identifier.addProperty( prop );
+ }
+ else {
+ rootClass.setIdentifier( ( KeyValue ) getValue() );
+ if (embedded) {
+ rootClass.setEmbeddedIdentifier( true );
+ }
+ else {
+ rootClass.setIdentifierProperty( prop );
+ final org.hibernate.mapping.MappedSuperclass superclass =
BinderHelper.getMappedSuperclassOrNull(
+ declaringClass,
+ inheritanceStatePerClass,
+ mappings
+ );
+ if (superclass != null) {
+ superclass.setDeclaredIdentifierProperty(prop);
+ }
+ else {
+ //we know the property is on the actual entity
+ rootClass.setDeclaredIdentifierProperty( prop );
+ }
+ }
+ }
+ }
+ else {
+ holder.addProperty( prop, columns, declaringClass );
+ }
+ return prop;
+ }
+
+ //used when the value is provided and the binding is done elsewhere
+ public Property makeProperty() {
+ validateMake();
+ log.debug( "Building property " + name );
+ Property prop = new Property();
+ prop.setName( name );
+ prop.setNodeName( name );
+ prop.setValue( value );
+ prop.setLazy( lazy );
+ prop.setCascade( cascade );
+ prop.setPropertyAccessorName( accessType.getType() );
+ Generated ann = property != null ?
+ property.getAnnotation( Generated.class ) :
+ null;
+ GenerationTime generated = ann != null ?
+ ann.value() :
+ null;
+ if ( generated != null ) {
+ if ( !GenerationTime.NEVER.equals( generated ) ) {
+ if ( property.isAnnotationPresent( javax.persistence.Version.class )
+ && GenerationTime.INSERT.equals( generated ) ) {
+ throw new AnnotationException(
+ "@Generated(INSERT) on a @Version property not allowed, use ALWAYS: "
+ + StringHelper.qualify( holder.getPath(), name )
+ );
+ }
+ insertable = false;
+ if ( GenerationTime.ALWAYS.equals( generated ) ) {
+ updatable = false;
+ }
+ prop.setGeneration( PropertyGeneration.parse( generated.toString().toLowerCase() )
);
+ }
+ }
+ NaturalId naturalId = property != null ?
+ property.getAnnotation( NaturalId.class ) :
+ null;
+ if ( naturalId != null ) {
+ if ( !naturalId.mutable() ) {
+ updatable = false;
+ }
+ prop.setNaturalIdentifier( true );
+ }
+ prop.setInsertable( insertable );
+ prop.setUpdateable( updatable );
+ OptimisticLock lockAnn = property != null ?
+ property.getAnnotation( OptimisticLock.class ) :
+ null;
+ if ( lockAnn != null ) {
+ prop.setOptimisticLocked( !lockAnn.excluded() );
+ //TODO this should go to the core as a mapping validation checking
+ if ( lockAnn.excluded() && (
+ property.isAnnotationPresent( javax.persistence.Version.class )
+ || property.isAnnotationPresent( Id.class )
+ || property.isAnnotationPresent( EmbeddedId.class ) ) ) {
+ throw new AnnotationException(
+ "(a)OptimisticLock.exclude=true incompatible with @Id, @EmbeddedId and @Version:
"
+ + StringHelper.qualify( holder.getPath(), name )
+ );
+ }
+ }
+ log.trace( "Cascading " + name + " with " + cascade );
+ this.mappingProperty = prop;
+ return prop;
+ }
+
+ public void setProperty(XProperty property) {
+ this.property = property;
+ }
+
+ public void setReturnedClass(XClass returnedClass) {
+ this.returnedClass = returnedClass;
+ }
+
+ public SimpleValueBinder getSimpleValueBinder() {
+ return simpleValueBinder;
+ }
+
+ public Value getValue() {
+ return value;
+ }
+
+ public void setId(boolean id) {
+ this.isId = id;
+ }
+
+ public void setInheritanceStatePerClass(Map<XClass, InheritanceState>
inheritanceStatePerClass) {
+ this.inheritanceStatePerClass = inheritanceStatePerClass;
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/annotations/QueryBinder.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/QueryBinder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/annotations/QueryBinder.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/QueryBinder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,424 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg.annotations;
+
+import java.util.HashMap;
+import javax.persistence.NamedNativeQueries;
+import javax.persistence.NamedNativeQuery;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.QueryHint;
+import javax.persistence.SqlResultSetMapping;
+import javax.persistence.SqlResultSetMappings;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.AssertionFailure;
+import org.hibernate.CacheMode;
+import org.hibernate.FlushMode;
+import org.hibernate.LockMode;
+import org.hibernate.annotations.CacheModeType;
+import org.hibernate.annotations.FlushModeType;
+import org.hibernate.cfg.BinderHelper;
+import org.hibernate.cfg.ExtendedMappings;
+import org.hibernate.cfg.NotYetImplementedException;
+import org.hibernate.engine.NamedQueryDefinition;
+import org.hibernate.engine.NamedSQLQueryDefinition;
+import org.hibernate.engine.query.sql.NativeSQLQueryReturn;
+import org.hibernate.engine.query.sql.NativeSQLQueryRootReturn;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Query binder
+ *
+ * @author Emmanuel Bernard
+ */
+public abstract class QueryBinder {
+ private static final Logger log = LoggerFactory.getLogger( QueryBinder.class );
+
+ public static void bindQuery(NamedQuery queryAnn, ExtendedMappings mappings, boolean
isDefault) {
+ if ( queryAnn == null ) return;
+ if ( BinderHelper.isDefault( queryAnn.name() ) ) {
+ throw new AnnotationException( "A named query must have a name when used in class
or package level" );
+ }
+ //EJBQL Query
+ QueryHint[] hints = queryAnn.hints();
+ String queryName = queryAnn.query();
+ NamedQueryDefinition query = new NamedQueryDefinition(
+ queryName,
+ getBoolean( queryName, "org.hibernate.cacheable", hints ),
+ getString( queryName, "org.hibernate.cacheRegion", hints ),
+ getTimeout( queryName, hints ),
+ getInteger( queryName, "org.hibernate.fetchSize", hints ),
+ getFlushMode( queryName, hints ),
+ getCacheMode( queryName, hints ),
+ getBoolean( queryName, "org.hibernate.readOnly", hints ),
+ getString( queryName, "org.hibernate.comment", hints ),
+ null
+ );
+ if ( isDefault ) {
+ mappings.addDefaultQuery( queryAnn.name(), query );
+ }
+ else {
+ mappings.addQuery( queryAnn.name(), query );
+ }
+ log.info( "Binding Named query: {} => {}", queryAnn.name(),
queryAnn.query() );
+ }
+
+
+ public static void bindNativeQuery(NamedNativeQuery queryAnn, ExtendedMappings mappings,
boolean isDefault) {
+ if ( queryAnn == null ) return;
+ //ResultSetMappingDefinition mappingDefinition = mappings.getResultSetMapping(
queryAnn.resultSetMapping() );
+ if ( BinderHelper.isDefault( queryAnn.name() ) ) {
+ throw new AnnotationException( "A named query must have a name when used in class
or package level" );
+ }
+ NamedSQLQueryDefinition query;
+ String resultSetMapping = queryAnn.resultSetMapping();
+ QueryHint[] hints = queryAnn.hints();
+ String queryName = queryAnn.query();
+ if ( !BinderHelper.isDefault( resultSetMapping ) ) {
+ //sql result set usage
+ query = new NamedSQLQueryDefinition(
+ queryName,
+ resultSetMapping,
+ null,
+ getBoolean( queryName, "org.hibernate.cacheable", hints ),
+ getString( queryName, "org.hibernate.cacheRegion", hints ),
+ getTimeout( queryName, hints ),
+ getInteger( queryName, "org.hibernate.fetchSize", hints ),
+ getFlushMode( queryName, hints ),
+ getCacheMode( queryName, hints ),
+ getBoolean( queryName, "org.hibernate.readOnly", hints ),
+ getString( queryName, "org.hibernate.comment", hints ),
+ null,
+ getBoolean( queryName, "org.hibernate.callable", hints )
+ );
+ }
+ else if ( !void.class.equals( queryAnn.resultClass() ) ) {
+ //class mapping usage
+ //FIXME should be done in a second pass due to entity name?
+ final NativeSQLQueryRootReturn entityQueryReturn =
+ new NativeSQLQueryRootReturn( "alias1", queryAnn.resultClass().getName(),
new HashMap(), LockMode.READ );
+ query = new NamedSQLQueryDefinition(
+ queryName,
+ new NativeSQLQueryReturn[] { entityQueryReturn },
+ null,
+ getBoolean( queryName, "org.hibernate.cacheable", hints ),
+ getString( queryName, "org.hibernate.cacheRegion", hints ),
+ getTimeout( queryName, hints ),
+ getInteger( queryName, "org.hibernate.fetchSize", hints ),
+ getFlushMode( queryName, hints ),
+ getCacheMode( queryName, hints ),
+ getBoolean( queryName, "org.hibernate.readOnly", hints ),
+ getString( queryName, "org.hibernate.comment", hints ),
+ null,
+ getBoolean( queryName, "org.hibernate.callable", hints )
+ );
+ }
+ else {
+ throw new NotYetImplementedException( "Pure native scalar queries are not yet
supported" );
+ }
+ if ( isDefault ) {
+ mappings.addDefaultSQLQuery( queryAnn.name(), query );
+ }
+ else {
+ mappings.addSQLQuery( queryAnn.name(), query );
+ }
+ log.info( "Binding named native query: {} => {}", queryAnn.name(),
queryAnn.query() );
+ }
+
+ public static void bindNativeQuery(org.hibernate.annotations.NamedNativeQuery queryAnn,
ExtendedMappings mappings) {
+ if ( queryAnn == null ) return;
+ //ResultSetMappingDefinition mappingDefinition = mappings.getResultSetMapping(
queryAnn.resultSetMapping() );
+ if ( BinderHelper.isDefault( queryAnn.name() ) ) {
+ throw new AnnotationException( "A named query must have a name when used in class
or package level" );
+ }
+ NamedSQLQueryDefinition query;
+ String resultSetMapping = queryAnn.resultSetMapping();
+ if ( !BinderHelper.isDefault( resultSetMapping ) ) {
+ //sql result set usage
+ query = new NamedSQLQueryDefinition(
+ queryAnn.query(),
+ resultSetMapping,
+ null,
+ queryAnn.cacheable(),
+ BinderHelper.isDefault( queryAnn.cacheRegion() ) ? null : queryAnn.cacheRegion(),
+ queryAnn.timeout() < 0 ? null : queryAnn.timeout(),
+ queryAnn.fetchSize() < 0 ? null : queryAnn.fetchSize(),
+ getFlushMode( queryAnn.flushMode() ),
+ getCacheMode( queryAnn.cacheMode() ),
+ queryAnn.readOnly(),
+ BinderHelper.isDefault( queryAnn.comment() ) ? null : queryAnn.comment(),
+ null,
+ queryAnn.callable()
+ );
+ }
+ else if ( !void.class.equals( queryAnn.resultClass() ) ) {
+ //class mapping usage
+ //FIXME should be done in a second pass due to entity name?
+ final NativeSQLQueryRootReturn entityQueryReturn =
+ new NativeSQLQueryRootReturn( "alias1", queryAnn.resultClass().getName(),
new HashMap(), LockMode.READ );
+ query = new NamedSQLQueryDefinition(
+ queryAnn.query(),
+ new NativeSQLQueryReturn[] { entityQueryReturn },
+ null,
+ queryAnn.cacheable(),
+ BinderHelper.isDefault( queryAnn.cacheRegion() ) ? null : queryAnn.cacheRegion(),
+ queryAnn.timeout() < 0 ? null : queryAnn.timeout(),
+ queryAnn.fetchSize() < 0 ? null : queryAnn.fetchSize(),
+ getFlushMode( queryAnn.flushMode() ),
+ getCacheMode( queryAnn.cacheMode() ),
+ queryAnn.readOnly(),
+ BinderHelper.isDefault( queryAnn.comment() ) ? null : queryAnn.comment(),
+ null,
+ queryAnn.callable()
+ );
+ }
+ else {
+ throw new NotYetImplementedException( "Pure native scalar queries are not yet
supported" );
+ }
+ mappings.addSQLQuery( queryAnn.name(), query );
+ log.info( "Binding named native query: {} => {}", queryAnn.name(),
queryAnn.query() );
+ }
+
+ public static void bindQueries(NamedQueries queriesAnn, ExtendedMappings mappings,
boolean isDefault) {
+ if ( queriesAnn == null ) return;
+ for (NamedQuery q : queriesAnn.value()) {
+ bindQuery( q, mappings, isDefault );
+ }
+ }
+
+ public static void bindNativeQueries(NamedNativeQueries queriesAnn, ExtendedMappings
mappings, boolean isDefault) {
+ if ( queriesAnn == null ) return;
+ for (NamedNativeQuery q : queriesAnn.value()) {
+ bindNativeQuery( q, mappings, isDefault );
+ }
+ }
+
+ public static void bindNativeQueries(
+ org.hibernate.annotations.NamedNativeQueries queriesAnn, ExtendedMappings mappings
+ ) {
+ if ( queriesAnn == null ) return;
+ for (org.hibernate.annotations.NamedNativeQuery q : queriesAnn.value()) {
+ bindNativeQuery( q, mappings );
+ }
+ }
+
+ public static void bindQuery(org.hibernate.annotations.NamedQuery queryAnn,
ExtendedMappings mappings) {
+ if ( queryAnn == null ) return;
+ if ( BinderHelper.isDefault( queryAnn.name() ) ) {
+ throw new AnnotationException( "A named query must have a name when used in class
or package level" );
+ }
+
+ FlushMode flushMode;
+ flushMode = getFlushMode( queryAnn.flushMode() );
+
+ NamedQueryDefinition query = new NamedQueryDefinition(
+ queryAnn.query(),
+ queryAnn.cacheable(),
+ BinderHelper.isDefault( queryAnn.cacheRegion() ) ? null : queryAnn.cacheRegion(),
+ queryAnn.timeout() < 0 ? null : queryAnn.timeout(),
+ queryAnn.fetchSize() < 0 ? null : queryAnn.fetchSize(),
+ flushMode,
+ getCacheMode( queryAnn.cacheMode() ),
+ queryAnn.readOnly(),
+ BinderHelper.isDefault( queryAnn.comment() ) ? null : queryAnn.comment(),
+ null
+ );
+
+ mappings.addQuery( queryAnn.name(), query );
+ if ( log.isInfoEnabled() ) log.info( "Binding named query: " +
queryAnn.name() + " => " + queryAnn.query() );
+ }
+
+ private static FlushMode getFlushMode(FlushModeType flushModeType) {
+ FlushMode flushMode;
+ switch ( flushModeType ) {
+ case ALWAYS:
+ flushMode = FlushMode.ALWAYS;
+ break;
+ case AUTO:
+ flushMode = FlushMode.AUTO;
+ break;
+ case COMMIT:
+ flushMode = FlushMode.COMMIT;
+ break;
+ case NEVER:
+ flushMode = FlushMode.MANUAL;
+ break;
+ case MANUAL:
+ flushMode = FlushMode.MANUAL;
+ break;
+ case PERSISTENCE_CONTEXT:
+ flushMode = null;
+ break;
+ default:
+ throw new AssertionFailure( "Unknown flushModeType: " + flushModeType );
+ }
+ return flushMode;
+ }
+
+ private static CacheMode getCacheMode(CacheModeType cacheModeType) {
+ switch ( cacheModeType ) {
+ case GET:
+ return CacheMode.GET;
+ case IGNORE:
+ return CacheMode.IGNORE;
+ case NORMAL:
+ return CacheMode.NORMAL;
+ case PUT:
+ return CacheMode.PUT;
+ case REFRESH:
+ return CacheMode.REFRESH;
+ default:
+ throw new AssertionFailure( "Unknown cacheModeType: " + cacheModeType );
+ }
+ }
+
+
+ public static void bindQueries(org.hibernate.annotations.NamedQueries queriesAnn,
ExtendedMappings mappings) {
+ if ( queriesAnn == null ) return;
+ for (org.hibernate.annotations.NamedQuery q : queriesAnn.value()) {
+ bindQuery( q, mappings );
+ }
+ }
+
+ public static void bindSqlResultsetMappings(SqlResultSetMappings ann, ExtendedMappings
mappings, boolean isDefault) {
+ if ( ann == null ) return;
+ for (SqlResultSetMapping rs : ann.value()) {
+ //no need to handle inSecondPass
+ mappings.addSecondPass( new ResultsetMappingSecondPass( rs, mappings, true ) );
+ }
+ }
+
+ public static void bindSqlResultsetMapping(SqlResultSetMapping ann, ExtendedMappings
mappings, boolean isDefault) {
+ //no need to handle inSecondPass
+ mappings.addSecondPass( new ResultsetMappingSecondPass( ann, mappings, isDefault ) );
+ }
+
+ private static CacheMode getCacheMode(String query, QueryHint[] hints) {
+ for (QueryHint hint : hints) {
+ if ( "org.hibernate.cacheMode".equals( hint.name() ) ) {
+ if ( hint.value().equalsIgnoreCase( CacheMode.GET.toString() ) ) {
+ return CacheMode.GET;
+ }
+ else if ( hint.value().equalsIgnoreCase( CacheMode.IGNORE.toString() ) ) {
+ return CacheMode.IGNORE;
+ }
+ else if ( hint.value().equalsIgnoreCase( CacheMode.NORMAL.toString() ) ) {
+ return CacheMode.NORMAL;
+ }
+ else if ( hint.value().equalsIgnoreCase( CacheMode.PUT.toString() ) ) {
+ return CacheMode.PUT;
+ }
+ else if ( hint.value().equalsIgnoreCase( CacheMode.REFRESH.toString() ) ) {
+ return CacheMode.REFRESH;
+ }
+ else {
+ throw new AnnotationException( "Unknown CacheMode in hint: " + query +
":" + hint.name() );
+ }
+ }
+ }
+ return null;
+ }
+
+ private static FlushMode getFlushMode(String query, QueryHint[] hints) {
+ for (QueryHint hint : hints) {
+ if ( "org.hibernate.flushMode".equals( hint.name() ) ) {
+ if ( hint.value().equalsIgnoreCase( FlushMode.ALWAYS.toString() ) ) {
+ return FlushMode.ALWAYS;
+ }
+ else if ( hint.value().equalsIgnoreCase( FlushMode.AUTO.toString() ) ) {
+ return FlushMode.AUTO;
+ }
+ else if ( hint.value().equalsIgnoreCase( FlushMode.COMMIT.toString() ) ) {
+ return FlushMode.COMMIT;
+ }
+ else if ( hint.value().equalsIgnoreCase( FlushMode.NEVER.toString() ) ) {
+ return FlushMode.MANUAL;
+ }
+ else if ( hint.value().equalsIgnoreCase( FlushMode.MANUAL.toString() ) ) {
+ return FlushMode.MANUAL;
+ }
+ else {
+ throw new AnnotationException( "Unknown FlushMode in hint: " + query +
":" + hint.name() );
+ }
+ }
+ }
+ return null;
+ }
+
+ private static boolean getBoolean(String query, String hintName, QueryHint[] hints) {
+ for (QueryHint hint : hints) {
+ if ( hintName.equals( hint.name() ) ) {
+ if ( hint.value().equalsIgnoreCase( "true" ) ) {
+ return true;
+ }
+ else if ( hint.value().equalsIgnoreCase( "false" ) ) {
+ return false;
+ }
+ else {
+ throw new AnnotationException( "Not a boolean in hint: " + query +
":" + hint.name() );
+ }
+ }
+ }
+ return false;
+ }
+
+ private static String getString(String query, String hintName, QueryHint[] hints) {
+ for (QueryHint hint : hints) {
+ if ( hintName.equals( hint.name() ) ) {
+ return hint.value();
+ }
+ }
+ return null;
+ }
+
+ private static Integer getInteger(String query, String hintName, QueryHint[] hints) {
+ for (QueryHint hint : hints) {
+ if ( hintName.equals( hint.name() ) ) {
+ try {
+ return Integer.decode( hint.value() );
+ }
+ catch (NumberFormatException nfe) {
+ throw new AnnotationException( "Not an integer in hint: " + query +
":" + hint.name(), nfe );
+ }
+ }
+ }
+ return null;
+ }
+
+ private static Integer getTimeout(String queryName, QueryHint[] hints) {
+ Integer timeout = getInteger( queryName, "javax.persistence.query.timeout",
hints );
+
+ if ( timeout != null ) {
+ // convert milliseconds to seconds
+ timeout = new Integer ((int)Math.round(timeout.doubleValue() / 1000.0 ) );
+ }
+ else {
+ // timeout is already in seconds
+ timeout = getInteger( queryName, "org.hibernate.timeout", hints );
+ }
+ return timeout;
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/QueryBinder.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/ResultsetMappingSecondPass.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/ResultsetMappingSecondPass.java)
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/ResultsetMappingSecondPass.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/ResultsetMappingSecondPass.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,268 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg.annotations;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.persistence.ColumnResult;
+import javax.persistence.EntityResult;
+import javax.persistence.FieldResult;
+import javax.persistence.SqlResultSetMapping;
+
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.cfg.BinderHelper;
+import org.hibernate.cfg.ExtendedMappings;
+import org.hibernate.cfg.QuerySecondPass;
+import org.hibernate.engine.ResultSetMappingDefinition;
+import org.hibernate.engine.query.sql.NativeSQLQueryRootReturn;
+import org.hibernate.engine.query.sql.NativeSQLQueryScalarReturn;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.ToOne;
+import org.hibernate.mapping.Value;
+import org.hibernate.util.StringHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class ResultsetMappingSecondPass implements QuerySecondPass {
+ private Logger log = LoggerFactory.getLogger( ResultsetMappingSecondPass.class );
+ private SqlResultSetMapping ann;
+ private ExtendedMappings mappings;
+ private boolean isDefault;
+
+ public ResultsetMappingSecondPass(SqlResultSetMapping ann, ExtendedMappings mappings,
boolean isDefault) {
+ this.ann = ann;
+ this.mappings = mappings;
+ this.isDefault = isDefault;
+ }
+
+ public void doSecondPass(Map persistentClasses) throws MappingException {
+ //TODO add parameters checkings
+ if ( ann == null ) return;
+ ResultSetMappingDefinition definition = new ResultSetMappingDefinition( ann.name() );
+ log.info( "Binding resultset mapping: {}", definition.getName() );
+
+ int entityAliasIndex = 0;
+
+ for (EntityResult entity : ann.entities()) {
+ //TODO parameterize lock mode?
+ List<FieldResult> properties = new ArrayList<FieldResult>();
+ List<String> propertyNames = new ArrayList<String>();
+ for (FieldResult field : entity.fields()) {
+ //use an ArrayList cause we might have several columns per root property
+ String name = field.name();
+ if ( name.indexOf( '.' ) == -1 ) {
+ //regular property
+ properties.add( field );
+ propertyNames.add( name );
+ }
+ else {
+ /**
+ * Reorder properties
+ * 1. get the parent property
+ * 2. list all the properties following the expected one in the parent property
+ * 3. calculate the lowest index and insert the property
+ */
+ PersistentClass pc = mappings.getClass( entity.entityClass().getName() );
+ if ( pc == null ) {
+ throw new MappingException(
+ "Entity not found " + entity.entityClass().getName()
+ + " in SqlResultsetMapping " + ann.name()
+ );
+ }
+ int dotIndex = name.lastIndexOf( '.' );
+ String reducedName = name.substring( 0, dotIndex );
+ Iterator parentPropIter = getSubPropertyIterator( pc, reducedName );
+ List followers = getFollowers( parentPropIter, reducedName, name );
+
+ int index = propertyNames.size();
+ int followersSize = followers.size();
+ for (int loop = 0; loop < followersSize; loop++) {
+ String follower = (String) followers.get( loop );
+ int currentIndex = getIndexOfFirstMatchingProperty( propertyNames, follower );
+ index = currentIndex != -1 && currentIndex < index ? currentIndex :
index;
+ }
+ propertyNames.add( index, name );
+ properties.add( index, field );
+ }
+ }
+
+ Set<String> uniqueReturnProperty = new HashSet<String>();
+ Map<String, ArrayList<String>> propertyResultsTmp = new HashMap<String,
ArrayList<String>>();
+ for ( Object property : properties ) {
+ final FieldResult propertyresult = ( FieldResult ) property;
+ final String name = propertyresult.name();
+ if ( "class".equals( name ) ) {
+ throw new MappingException(
+ "class is not a valid property name to use in a @FieldResult, use
@Entity(discriminatorColumn) instead"
+ );
+ }
+
+ if ( uniqueReturnProperty.contains( name ) ) {
+ throw new MappingException(
+ "duplicate @FieldResult for property " + name +
+ " on @Entity " + entity.entityClass().getName() + " in " +
ann.name()
+ );
+ }
+ uniqueReturnProperty.add( name );
+
+ final String quotingNormalizedColumnName = mappings.getObjectNameNormalizer()
+ .normalizeIdentifierQuoting( propertyresult.column() );
+
+ String key = StringHelper.root( name );
+ ArrayList<String> intermediateResults = propertyResultsTmp.get( key );
+ if ( intermediateResults == null ) {
+ intermediateResults = new ArrayList<String>();
+ propertyResultsTmp.put( key, intermediateResults );
+ }
+ intermediateResults.add( quotingNormalizedColumnName );
+ }
+
+ Map<String, String[]> propertyResults = new HashMap<String,String[]>();
+ for ( Map.Entry<String, ArrayList<String>> entry :
propertyResultsTmp.entrySet() ) {
+ propertyResults.put(
+ entry.getKey(),
+ entry.getValue().toArray( new String[ entry.getValue().size() ] )
+ );
+ }
+
+ if ( !BinderHelper.isDefault( entity.discriminatorColumn() ) ) {
+ final String quotingNormalizedName =
mappings.getObjectNameNormalizer().normalizeIdentifierQuoting(
+ entity.discriminatorColumn()
+ );
+ propertyResults.put( "class", new String[] { quotingNormalizedName } );
+ }
+
+ if ( propertyResults.isEmpty() ) {
+ propertyResults = java.util.Collections.emptyMap();
+ }
+
+ NativeSQLQueryRootReturn result = new NativeSQLQueryRootReturn(
+ "alias" + entityAliasIndex++,
+ entity.entityClass().getName(),
+ propertyResults,
+ LockMode.READ
+ );
+ definition.addQueryReturn( result );
+ }
+
+ for ( ColumnResult column : ann.columns() ) {
+ definition.addQueryReturn(
+ new NativeSQLQueryScalarReturn(
+ mappings.getObjectNameNormalizer().normalizeIdentifierQuoting(
+ column.name()
+ ),
+ null
+ )
+ );
+ }
+
+ if ( isDefault ) {
+ mappings.addDefaultResultSetMapping( definition );
+ }
+ else {
+ mappings.addResultSetMapping( definition );
+ }
+ }
+
+ @SuppressWarnings({ "unchecked" })
+ private List getFollowers(Iterator parentPropIter, String reducedName, String name) {
+ boolean hasFollowers = false;
+ List followers = new ArrayList();
+ while ( parentPropIter.hasNext() ) {
+ String currentPropertyName = ( (Property) parentPropIter.next() ).getName();
+ String currentName = reducedName + '.' + currentPropertyName;
+ if ( hasFollowers ) {
+ followers.add( currentName );
+ }
+ if ( name.equals( currentName ) ) hasFollowers = true;
+ }
+ return followers;
+ }
+
+ private Iterator getSubPropertyIterator(PersistentClass pc, String reducedName) {
+ Value value = pc.getRecursiveProperty( reducedName ).getValue();
+ Iterator parentPropIter;
+ if ( value instanceof Component ) {
+ Component comp = (Component) value;
+ parentPropIter = comp.getPropertyIterator();
+ }
+ else if ( value instanceof ToOne ) {
+ ToOne toOne = (ToOne) value;
+ PersistentClass referencedPc = mappings.getClass( toOne.getReferencedEntityName() );
+ if ( toOne.getReferencedPropertyName() != null ) {
+ try {
+ parentPropIter = ( (Component) referencedPc.getRecursiveProperty(
+ toOne.getReferencedPropertyName()
+ ).getValue() ).getPropertyIterator();
+ }
+ catch (ClassCastException e) {
+ throw new MappingException(
+ "dotted notation reference neither a component nor a many/one to one",
e
+ );
+ }
+ }
+ else {
+ try {
+ if ( referencedPc.getIdentifierMapper() == null ) {
+ parentPropIter = ( (Component) referencedPc.getIdentifierProperty()
+ .getValue() ).getPropertyIterator();
+ }
+ else {
+ parentPropIter = referencedPc.getIdentifierMapper().getPropertyIterator();
+ }
+ }
+ catch (ClassCastException e) {
+ throw new MappingException(
+ "dotted notation reference neither a component nor a many/one to one",
e
+ );
+ }
+ }
+ }
+ else {
+ throw new MappingException( "dotted notation reference neither a component nor a
many/one to one" );
+ }
+ return parentPropIter;
+ }
+
+ private static int getIndexOfFirstMatchingProperty(List propertyNames, String follower)
{
+ int propertySize = propertyNames.size();
+ for (int propIndex = 0; propIndex < propertySize; propIndex++) {
+ if ( ( (String) propertyNames.get( propIndex ) ).startsWith( follower ) ) {
+ return propIndex;
+ }
+ }
+ return -1;
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/ResultsetMappingSecondPass.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/annotations/SetBinder.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/SetBinder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/annotations/SetBinder.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/annotations/SetBinder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,63 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg.annotations;
+
+import org.hibernate.annotations.OrderBy;
+import org.hibernate.cfg.Environment;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.PersistentClass;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Bind a set.
+ *
+ * @author Matthew Inger
+ */
+public class SetBinder extends CollectionBinder {
+ private final Logger log = LoggerFactory.getLogger( SetBinder.class );
+
+ public SetBinder() {
+ }
+
+ public SetBinder(boolean sorted) {
+ super( sorted );
+ }
+
+ protected Collection createCollection(PersistentClass persistentClass) {
+ return new org.hibernate.mapping.Set( getMappings(), persistentClass );
+ }
+
+ public void setSqlOrderBy(OrderBy orderByAnn) {
+ // *annotation* binder, jdk 1.5, ... am i missing something?
+ if ( orderByAnn != null ) {
+ if ( Environment.jvmSupportsLinkedHashCollections() ) {
+ super.setSqlOrderBy( orderByAnn );
+ }
+ else {
+ log.warn( "Attribute \"order-by\" ignored in JDK1.3 or less" );
+ }
+ }
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/SetBinder.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/annotations/SimpleValueBinder.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/SimpleValueBinder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/annotations/SimpleValueBinder.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/SimpleValueBinder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,355 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg.annotations;
+
+import java.io.Serializable;
+import java.sql.Types;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Properties;
+import javax.persistence.Enumerated;
+import javax.persistence.Lob;
+import javax.persistence.MapKeyEnumerated;
+import javax.persistence.MapKeyTemporal;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.AssertionFailure;
+import org.hibernate.Hibernate;
+import org.hibernate.annotations.Parameter;
+import org.hibernate.annotations.Type;
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.cfg.BinderHelper;
+import org.hibernate.cfg.Ejb3Column;
+import org.hibernate.cfg.Ejb3JoinColumn;
+import org.hibernate.cfg.ExtendedMappings;
+import org.hibernate.cfg.NotYetImplementedException;
+import org.hibernate.cfg.PkDrivenByDefaultMapsIdSecondPass;
+import org.hibernate.cfg.SetSimpleValueTypeSecondPass;
+import org.hibernate.mapping.SimpleValue;
+import org.hibernate.mapping.Table;
+import org.hibernate.type.CharacterArrayClobType;
+import org.hibernate.type.EnumType;
+import org.hibernate.type.PrimitiveCharacterArrayClobType;
+import org.hibernate.type.SerializableToBlobType;
+import org.hibernate.type.WrappedMaterializedBlobType;
+import org.hibernate.util.StringHelper;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class SimpleValueBinder {
+ private Logger log = LoggerFactory.getLogger( SimpleValueBinder.class );
+ private String propertyName;
+ private String returnedClassName;
+ private Ejb3Column[] columns;
+ private String persistentClassName;
+ private String explicitType = "";
+ private Properties typeParameters = new Properties();
+ private ExtendedMappings mappings;
+ private Table table;
+ private SimpleValue simpleValue;
+ private boolean isVersion;
+ //is a Map key
+ private boolean key;
+ private String referencedEntityName;
+
+ public void setReferencedEntityName(String referencedEntityName) {
+ this.referencedEntityName = referencedEntityName;
+ }
+
+ public boolean isVersion() {
+ return isVersion;
+ }
+
+ public void setVersion(boolean isVersion) {
+ this.isVersion = isVersion;
+ }
+
+ public void setPropertyName(String propertyName) {
+ this.propertyName = propertyName;
+ }
+
+ public void setReturnedClassName(String returnedClassName) {
+ this.returnedClassName = returnedClassName;
+ }
+
+ public void setTable(Table table) {
+ this.table = table;
+ }
+
+ public void setColumns(Ejb3Column[] columns) {
+ this.columns = columns;
+ }
+
+
+ public void setPersistentClassName(String persistentClassName) {
+ this.persistentClassName = persistentClassName;
+ }
+
+ //TODO execute it lazily to be order safe
+ public void setType(XProperty property, XClass returnedClass) {
+ if ( returnedClass == null ) return; //we cannot guess anything
+ XClass returnedClassOrElement = returnedClass;
+ boolean isArray = false;
+ if ( property.isArray() ) {
+ returnedClassOrElement = property.getElementClass();
+ isArray = true;
+ }
+ Properties typeParameters = this.typeParameters;
+ typeParameters.clear();
+ String type = BinderHelper.ANNOTATION_STRING_DEFAULT;
+ if ( (!key && property.isAnnotationPresent( Temporal.class ) )
+ || (key && property.isAnnotationPresent( MapKeyTemporal.class ) )) {
+
+ boolean isDate;
+ if ( mappings.getReflectionManager().equals( returnedClassOrElement, Date.class ) ) {
+ isDate = true;
+ }
+ else if ( mappings.getReflectionManager().equals( returnedClassOrElement,
Calendar.class ) ) {
+ isDate = false;
+ }
+ else {
+ throw new AnnotationException(
+ "@Temporal should only be set on a java.util.Date or java.util.Calendar
property: "
+ + StringHelper.qualify( persistentClassName, propertyName )
+ );
+ }
+ final TemporalType temporalType = getTemporalType( property );
+ switch ( temporalType ) {
+ case DATE:
+ type = isDate ? "date" : "calendar_date";
+ break;
+ case TIME:
+ type = "time";
+ if ( !isDate ) {
+ throw new NotYetImplementedException(
+ "Calendar cannot persist TIME only"
+ + StringHelper.qualify( persistentClassName, propertyName )
+ );
+ }
+ break; case TIMESTAMP:
+ type = isDate ? "timestamp" : "calendar";
+ break;
+ default:
+ throw new AssertionFailure( "Unknown temporal type: " + temporalType );
+ }
+ }
+ else if ( property.isAnnotationPresent( Lob.class ) ) {
+
+ if ( mappings.getReflectionManager().equals( returnedClassOrElement,
java.sql.Clob.class ) ) {
+ type = "clob";
+ }
+ else if ( mappings.getReflectionManager().equals( returnedClassOrElement,
java.sql.Blob.class ) ) {
+ type = "blob";
+ }
+ else if ( mappings.getReflectionManager().equals( returnedClassOrElement, String.class
) ) {
+ type = Hibernate.MATERIALIZED_CLOB.getName();
+ }
+ else if ( mappings.getReflectionManager().equals( returnedClassOrElement,
Character.class ) && isArray ) {
+ type = CharacterArrayClobType.class.getName();
+ }
+ else if ( mappings.getReflectionManager().equals( returnedClassOrElement, char.class )
&& isArray ) {
+ type = PrimitiveCharacterArrayClobType.class.getName();
+ }
+ else if ( mappings.getReflectionManager().equals( returnedClassOrElement, Byte.class )
&& isArray ) {
+ type = WrappedMaterializedBlobType.class.getName();
+ }
+ else if ( mappings.getReflectionManager().equals( returnedClassOrElement, byte.class )
&& isArray ) {
+ type = Hibernate.MATERIALIZED_BLOB.getName();
+ }
+ else if ( mappings.getReflectionManager()
+ .toXClass( Serializable.class )
+ .isAssignableFrom( returnedClassOrElement ) ) {
+ type = SerializableToBlobType.class.getName();
+ //typeParameters = new Properties();
+ typeParameters.setProperty(
+ SerializableToBlobType.CLASS_NAME,
+ returnedClassOrElement.getName()
+ );
+ }
+ else {
+ type = "blob";
+ }
+ }
+ //implicit type will check basic types and Serializable classes
+ if ( columns == null ) {
+ throw new AssertionFailure( "SimpleValueBinder.setColumns should be set before
SimpleValueBinder.setType" );
+ }
+ if ( BinderHelper.ANNOTATION_STRING_DEFAULT.equals( type ) ) {
+ if ( returnedClassOrElement.isEnum() ) {
+ type = EnumType.class.getName();
+ typeParameters = new Properties();
+ typeParameters.setProperty( EnumType.ENUM, returnedClassOrElement.getName() );
+ String schema = columns[0].getTable().getSchema();
+ schema = schema == null ? "" : schema;
+ String catalog = columns[0].getTable().getCatalog();
+ catalog = catalog == null ? "" : catalog;
+ typeParameters.setProperty( EnumType.SCHEMA, schema );
+ typeParameters.setProperty( EnumType.CATALOG, catalog );
+ typeParameters.setProperty( EnumType.TABLE, columns[0].getTable().getName() );
+ typeParameters.setProperty( EnumType.COLUMN, columns[0].getName() );
+ javax.persistence.EnumType enumType = getEnumType( property );
+ if ( enumType != null ) {
+ if ( javax.persistence.EnumType.ORDINAL.equals( enumType ) ) {
+ typeParameters.setProperty( EnumType.TYPE, String.valueOf( Types.INTEGER ) );
+ }
+ else if ( javax.persistence.EnumType.STRING.equals( enumType ) ) {
+ typeParameters.setProperty( EnumType.TYPE, String.valueOf( Types.VARCHAR ) );
+ }
+ else {
+ throw new AssertionFailure( "Unknown EnumType: " + enumType );
+ }
+ }
+ }
+ }
+ explicitType = type;
+ this.typeParameters = typeParameters;
+ Type annType = property.getAnnotation( Type.class );
+ setExplicitType( annType );
+ }
+
+ private javax.persistence.EnumType getEnumType(XProperty property) {
+ javax.persistence.EnumType enumType = null;
+ if (key) {
+ MapKeyEnumerated enumAnn = property.getAnnotation( MapKeyEnumerated.class );
+ if ( enumAnn != null ) {
+ enumType = enumAnn.value();
+ }
+ }
+ else {
+ Enumerated enumAnn = property.getAnnotation( Enumerated.class );
+ if ( enumAnn != null ) {
+ enumType = enumAnn.value();
+ }
+ }
+ return enumType;
+ }
+
+ private TemporalType getTemporalType(XProperty property) {
+ if (key) {
+ MapKeyTemporal ann = property.getAnnotation( MapKeyTemporal.class );
+ return ann.value();
+ }
+ else {
+ Temporal ann = property.getAnnotation( Temporal.class );
+ return ann.value();
+ }
+ }
+
+ public void setExplicitType(String explicitType) {
+ this.explicitType = explicitType;
+ }
+
+ //FIXME raise an assertion failure if setExplicitType(String) and setExplicitType(Type)
are use at the same time
+ public void setExplicitType(Type typeAnn) {
+ if ( typeAnn != null ) {
+ explicitType = typeAnn.type();
+ typeParameters.clear();
+ for (Parameter param : typeAnn.parameters()) {
+ typeParameters.setProperty( param.name(), param.value() );
+ }
+ }
+ }
+
+ public void setMappings(ExtendedMappings mappings) {
+ this.mappings = mappings;
+ }
+
+ private void validate() {
+ //TODO check necessary params
+ Ejb3Column.checkPropertyConsistency( columns, propertyName );
+ }
+
+ public SimpleValue make() {
+
+ validate();
+ log.debug( "building SimpleValue for {}", propertyName );
+ if ( table == null ) {
+ table = columns[0].getTable();
+ }
+ simpleValue = new SimpleValue( mappings, table );
+
+ linkWithValue();
+
+ boolean isInSecondPass = mappings.isInSecondPass();
+ SetSimpleValueTypeSecondPass secondPass = new SetSimpleValueTypeSecondPass(this);
+ if (!isInSecondPass) {
+ //Defer this to the second pass
+ mappings.addSecondPass(secondPass);
+ }
+ else {
+ //We are already in second pass
+ fillSimpleValue();
+ }
+ return simpleValue;
+ }
+
+ public void linkWithValue() {
+ if ( columns[0].isNameDeferred() && ! mappings.isInSecondPass() &&
referencedEntityName != null) {
+ mappings.addSecondPass(
+ new PkDrivenByDefaultMapsIdSecondPass( referencedEntityName, ( Ejb3JoinColumn[])
columns, simpleValue)
+ );
+ }
+ else {
+ for ( Ejb3Column column : columns) {
+ column.linkWithValue( simpleValue );
+ }
+ }
+ }
+
+ public void fillSimpleValue() {
+
+ log.debug( "setting SimpleValue typeName for {}", propertyName );
+
+ String type = BinderHelper.isDefault( explicitType ) ? returnedClassName :
explicitType;
+ org.hibernate.mapping.TypeDef typeDef = mappings.getTypeDef( type );
+ if ( typeDef != null ) {
+ type = typeDef.getTypeClass();
+ simpleValue.setTypeParameters( typeDef.getParameters() );
+ }
+ if ( typeParameters != null && typeParameters.size() != 0 ) {
+ //explicit type params takes precedence over type def params
+ simpleValue.setTypeParameters( typeParameters );
+ }
+ simpleValue.setTypeName( type );
+ if ( persistentClassName != null ) {
+ simpleValue.setTypeUsingReflection( persistentClassName, propertyName );
+ }
+
+ if ( !simpleValue.isTypeSpecified() && isVersion()) {
+ simpleValue.setTypeName( "integer" );
+ }
+
+ }
+
+ public void setKey(boolean key) {
+ this.key = key;
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/SimpleValueBinder.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/annotations/TableBinder.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/TableBinder.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/annotations/TableBinder.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/TableBinder.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,565 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg.annotations;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import javax.persistence.UniqueConstraint;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.AssertionFailure;
+import org.hibernate.annotations.Index;
+import org.hibernate.util.StringHelper;
+import org.hibernate.util.CollectionHelper;
+import org.hibernate.cfg.BinderHelper;
+import org.hibernate.cfg.Ejb3JoinColumn;
+import org.hibernate.cfg.ExtendedMappings;
+import org.hibernate.cfg.IndexOrUniqueKeySecondPass;
+import org.hibernate.cfg.ObjectNameNormalizer;
+import org.hibernate.cfg.ObjectNameSource;
+import org.hibernate.cfg.NamingStrategy;
+import org.hibernate.cfg.UniqueConstraintHolder;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.DependantValue;
+import org.hibernate.mapping.JoinedSubclass;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.SimpleValue;
+import org.hibernate.mapping.Table;
+import org.hibernate.mapping.ToOne;
+import org.hibernate.mapping.Value;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Table related operations
+ *
+ * @author Emmanuel Bernard
+ */
+@SuppressWarnings("unchecked")
+public class TableBinder {
+ //TODO move it to a getter/setter strategy
+ private static Logger log = LoggerFactory.getLogger( TableBinder.class );
+ private String schema;
+ private String catalog;
+ private String name;
+ private boolean isAbstract;
+ private List<UniqueConstraintHolder> uniqueConstraints;
+// private List<String[]> uniqueConstraints;
+ String constraints;
+ Table denormalizedSuperTable;
+ ExtendedMappings mappings;
+ private String ownerEntityTable;
+ private String associatedEntityTable;
+ private String propertyName;
+ private String ownerEntity;
+ private String associatedEntity;
+ private boolean isJPA2ElementCollection;
+
+ public void setSchema(String schema) {
+ this.schema = schema;
+ }
+
+ public void setCatalog(String catalog) {
+ this.catalog = catalog;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setAbstract(boolean anAbstract) {
+ isAbstract = anAbstract;
+ }
+
+ public void setUniqueConstraints(UniqueConstraint[] uniqueConstraints) {
+ this.uniqueConstraints = TableBinder.buildUniqueConstraintHolders( uniqueConstraints
);
+ }
+
+ public void setConstraints(String constraints) {
+ this.constraints = constraints;
+ }
+
+ public void setDenormalizedSuperTable(Table denormalizedSuperTable) {
+ this.denormalizedSuperTable = denormalizedSuperTable;
+ }
+
+ public void setMappings(ExtendedMappings mappings) {
+ this.mappings = mappings;
+ }
+
+ public void setJPA2ElementCollection(boolean isJPA2ElementCollection) {
+ this.isJPA2ElementCollection = isJPA2ElementCollection;
+ }
+
+ private static class AssociationTableNameSource implements ObjectNameSource {
+ private final String explicitName;
+ private final String logicalName;
+
+ private AssociationTableNameSource(String explicitName, String logicalName) {
+ this.explicitName = explicitName;
+ this.logicalName = logicalName;
+ }
+
+ public String getExplicitName() {
+ return explicitName;
+ }
+
+ public String getLogicalName() {
+ return logicalName;
+ }
+ }
+
+ // only bind association table currently
+ public Table bind() {
+ //logicalName only accurate for assoc table...
+ final String unquotedOwnerTable = StringHelper.unquote( ownerEntityTable );
+ final String unquotedAssocTable = StringHelper.unquote( associatedEntityTable );
+
+ //@ElementCollection use ownerEntity_property instead of the cleaner
ownerTableName_property
+ // ownerEntity can be null when the table name is explicitly set
+ final String ownerObjectName = isJPA2ElementCollection && ownerEntity != null
?
+ StringHelper.unqualify( ownerEntity ) : unquotedOwnerTable;
+ final ObjectNameSource nameSource = buildNameContext(
+ ownerObjectName,
+ unquotedAssocTable );
+
+ final boolean ownerEntityTableQuoted = StringHelper.isQuoted( ownerEntityTable );
+ final boolean associatedEntityTableQuoted = StringHelper.isQuoted(
associatedEntityTable );
+ final ObjectNameNormalizer.NamingStrategyHelper namingStrategyHelper = new
ObjectNameNormalizer.NamingStrategyHelper() {
+ public String determineImplicitName(NamingStrategy strategy) {
+
+ final String strategyResult = strategy.collectionTableName(
+ ownerEntity,
+ ownerObjectName,
+ associatedEntity,
+ unquotedAssocTable,
+ propertyName
+
+ );
+ return ownerEntityTableQuoted || associatedEntityTableQuoted
+ ? StringHelper.quote( strategyResult )
+ : strategyResult;
+ }
+
+ public String handleExplicitName(NamingStrategy strategy, String name) {
+ return strategy.tableName( name );
+ }
+ };
+
+ return buildAndFillTable(
+ schema,
+ catalog,
+ nameSource,
+ namingStrategyHelper,
+ isAbstract,
+ uniqueConstraints,
+ constraints,
+ denormalizedSuperTable,
+ mappings,
+ null
+ );
+ }
+
+ private ObjectNameSource buildNameContext(String unquotedOwnerTable, String
unquotedAssocTable) {
+ String logicalName = mappings.getNamingStrategy().logicalCollectionTableName(
+ name,
+ unquotedOwnerTable,
+ unquotedAssocTable,
+ propertyName
+ );
+ if ( StringHelper.isQuoted( ownerEntityTable ) || StringHelper.isQuoted(
associatedEntityTable ) ) {
+ logicalName = StringHelper.quote( logicalName );
+ }
+
+ return new AssociationTableNameSource( name, logicalName );
+ }
+
+ public static Table buildAndFillTable(
+ String schema,
+ String catalog,
+ ObjectNameSource nameSource,
+ ObjectNameNormalizer.NamingStrategyHelper namingStrategyHelper,
+ boolean isAbstract,
+ List<UniqueConstraintHolder> uniqueConstraints,
+ String constraints,
+ Table denormalizedSuperTable,
+ ExtendedMappings mappings,
+ String subselect) {
+ schema = BinderHelper.isDefault( schema ) ? mappings.getSchemaName() : schema;
+ catalog = BinderHelper.isDefault( catalog ) ? mappings.getCatalogName() : catalog;
+
+ String realTableName = mappings.getObjectNameNormalizer().normalizeDatabaseIdentifier(
+ nameSource.getExplicitName(),
+ namingStrategyHelper
+ );
+
+ final Table table;
+ if ( denormalizedSuperTable != null ) {
+ table = mappings.addDenormalizedTable(
+ schema,
+ catalog,
+ realTableName,
+ isAbstract,
+ subselect,
+ denormalizedSuperTable
+ );
+ }
+ else {
+ table = mappings.addTable(
+ schema,
+ catalog,
+ realTableName,
+ subselect,
+ isAbstract
+ );
+ }
+
+ if ( uniqueConstraints != null && uniqueConstraints.size() > 0 ) {
+ mappings.addUniqueConstraintHolders( table, uniqueConstraints );
+ }
+
+ if ( constraints != null ) table.addCheckConstraint( constraints );
+
+ // logicalName is null if we are in the second pass
+ final String logicalName = nameSource.getLogicalName();
+ if ( logicalName != null ) {
+ mappings.addTableBinding( schema, catalog, logicalName, realTableName,
denormalizedSuperTable );
+ }
+ return table;
+ }
+
+ /**
+ *
+ * @param schema
+ * @param catalog
+ * @param realTableName
+ * @param logicalName
+ * @param isAbstract
+ * @param uniqueConstraints
+ * @param constraints
+ * @param denormalizedSuperTable
+ * @param mappings
+ * @return
+ *
+ * @deprecated Use {@link #buildAndFillTable} instead.
+ */
+ @SuppressWarnings({ "JavaDoc" })
+ public static Table fillTable(
+ String schema, String catalog, String realTableName, String logicalName, boolean
isAbstract,
+ List uniqueConstraints, String constraints, Table denormalizedSuperTable,
ExtendedMappings mappings
+ ) {
+ schema = BinderHelper.isDefault( schema ) ? mappings.getSchemaName() : schema;
+ catalog = BinderHelper.isDefault( catalog ) ? mappings.getCatalogName() : catalog;
+ Table table;
+ if ( denormalizedSuperTable != null ) {
+ table = mappings.addDenormalizedTable(
+ schema,
+ catalog,
+ realTableName,
+ isAbstract,
+ null, //subselect
+ denormalizedSuperTable
+ );
+ }
+ else {
+ table = mappings.addTable(
+ schema,
+ catalog,
+ realTableName,
+ null, //subselect
+ isAbstract
+ );
+ }
+ if ( uniqueConstraints != null && uniqueConstraints.size() > 0 ) {
+ mappings.addUniqueConstraints( table, uniqueConstraints );
+ }
+ if ( constraints != null ) table.addCheckConstraint( constraints );
+ //logicalName is null if we are in the second pass
+ if ( logicalName != null ) {
+ mappings.addTableBinding( schema, catalog, logicalName, realTableName,
denormalizedSuperTable );
+ }
+ return table;
+ }
+
+ public static void bindFk(
+ PersistentClass referencedEntity, PersistentClass destinationEntity, Ejb3JoinColumn[]
columns,
+ SimpleValue value,
+ boolean unique, ExtendedMappings mappings
+ ) {
+ PersistentClass associatedClass;
+ if ( destinationEntity != null ) {
+ //overridden destination
+ associatedClass = destinationEntity;
+ }
+ else {
+ associatedClass = columns[0].getPropertyHolder() == null
+ ? null
+ : columns[0].getPropertyHolder().getPersistentClass();
+ }
+ final String mappedByProperty = columns[0].getMappedBy();
+ if ( StringHelper.isNotEmpty( mappedByProperty ) ) {
+ /**
+ * Get the columns of the mapped-by property
+ * copy them and link the copy to the actual value
+ */
+ log.debug("Retrieving property {}.{}", associatedClass.getEntityName(),
mappedByProperty);
+
+ final Property property = associatedClass.getRecursiveProperty(
columns[0].getMappedBy() );
+ Iterator mappedByColumns;
+ if ( property.getValue() instanceof Collection ) {
+ Collection collection = ( (Collection) property.getValue() );
+ Value element = collection.getElement();
+ if ( element == null ) {
+ throw new AnnotationException(
+ "Illegal use of mappedBy on both sides of the relationship: "
+ + associatedClass.getEntityName() + "." + mappedByProperty
+ );
+ }
+ mappedByColumns = element.getColumnIterator();
+ }
+ else {
+ mappedByColumns = property.getValue().getColumnIterator();
+ }
+ while ( mappedByColumns.hasNext() ) {
+ Column column = (Column) mappedByColumns.next();
+ columns[0].overrideFromReferencedColumnIfNecessary( column );
+ columns[0].linkValueUsingAColumnCopy( column, value );
+ }
+ }
+ else if ( columns[0].isImplicit() ) {
+ /**
+ * if columns are implicit, then create the columns based on the
+ * referenced entity id columns
+ */
+ Iterator idColumns;
+ if ( referencedEntity instanceof JoinedSubclass ) {
+ idColumns = referencedEntity.getKey().getColumnIterator();
+ }
+ else {
+ idColumns = referencedEntity.getIdentifier().getColumnIterator();
+ }
+ while ( idColumns.hasNext() ) {
+ Column column = (Column) idColumns.next();
+ columns[0].overrideFromReferencedColumnIfNecessary( column );
+ columns[0].linkValueUsingDefaultColumnNaming( column, referencedEntity, value );
+ }
+ }
+ else {
+ int fkEnum = Ejb3JoinColumn.checkReferencedColumnsType( columns, referencedEntity,
mappings );
+
+ if ( Ejb3JoinColumn.NON_PK_REFERENCE == fkEnum ) {
+ String referencedPropertyName;
+ if ( value instanceof ToOne ) {
+ referencedPropertyName = ( (ToOne) value ).getReferencedPropertyName();
+ }
+ else if ( value instanceof DependantValue ) {
+ String propertyName = columns[0].getPropertyName();
+ if ( propertyName != null ) {
+ Collection collection = (Collection) referencedEntity.getRecursiveProperty(
propertyName )
+ .getValue();
+ referencedPropertyName = collection.getReferencedPropertyName();
+ }
+ else {
+ throw new AnnotationException( "SecondaryTable JoinColumn cannot reference a
non primary key" );
+ }
+
+ }
+ else {
+ throw new AssertionFailure(
+ "Do a property ref on an unexpected Value type: "
+ + value.getClass().getName()
+ );
+ }
+ if ( referencedPropertyName == null ) {
+ throw new AssertionFailure(
+ "No property ref found while expected"
+ );
+ }
+ Property synthProp = referencedEntity.getRecursiveProperty( referencedPropertyName
);
+ if ( synthProp == null ) {
+ throw new AssertionFailure(
+ "Cannot find synthProp: " + referencedEntity.getEntityName() +
"." + referencedPropertyName
+ );
+ }
+ linkJoinColumnWithValueOverridingNameIfImplicit(
+ referencedEntity, synthProp.getColumnIterator(), columns, value
+ );
+
+ }
+ else {
+ if ( Ejb3JoinColumn.NO_REFERENCE == fkEnum ) {
+ //implicit case, we hope PK and FK columns are in the same order
+ if ( columns.length != referencedEntity.getIdentifier().getColumnSpan() ) {
+ throw new AnnotationException(
+ "A Foreign key refering " + referencedEntity.getEntityName()
+ + " from " + associatedClass.getEntityName()
+ + " has the wrong number of column. should be " +
referencedEntity.getIdentifier()
+ .getColumnSpan()
+ );
+ }
+ linkJoinColumnWithValueOverridingNameIfImplicit(
+ referencedEntity,
+ referencedEntity.getIdentifier().getColumnIterator(),
+ columns,
+ value
+ );
+ }
+ else {
+ //explicit referencedColumnName
+ Iterator idColItr = referencedEntity.getKey().getColumnIterator();
+ org.hibernate.mapping.Column col;
+ Table table = referencedEntity.getTable(); //works cause the pk has to be on the
primary table
+ if ( !idColItr.hasNext() ) log.debug( "No column in the identifier!" );
+ while ( idColItr.hasNext() ) {
+ boolean match = false;
+ //for each PK column, find the associated FK column.
+ col = (org.hibernate.mapping.Column) idColItr.next();
+ for (Ejb3JoinColumn joinCol : columns) {
+ String referencedColumn = joinCol.getReferencedColumn();
+ referencedColumn = mappings.getPhysicalColumnName( referencedColumn, table );
+ //In JPA 2 referencedColumnName is case insensitive
+ if ( referencedColumn.equalsIgnoreCase( col.getQuotedName() ) ) {
+ //proper join column
+ if ( joinCol.isNameDeferred() ) {
+ joinCol.linkValueUsingDefaultColumnNaming(
+ col, referencedEntity, value
+ );
+ }
+ else {
+ joinCol.linkWithValue( value );
+ }
+ joinCol.overrideFromReferencedColumnIfNecessary( col );
+ match = true;
+ break;
+ }
+ }
+ if ( !match ) {
+ throw new AnnotationException(
+ "Column name " + col.getName() + " of "
+ + referencedEntity.getEntityName() + " not found in
JoinColumns.referencedColumnName"
+ );
+ }
+ }
+ }
+ }
+ }
+ value.createForeignKey();
+ if ( unique ) {
+ createUniqueConstraint( value );
+ }
+ }
+
+ public static void linkJoinColumnWithValueOverridingNameIfImplicit(
+ PersistentClass referencedEntity, Iterator columnIterator, Ejb3JoinColumn[] columns,
SimpleValue value
+ ) {
+ for (Ejb3JoinColumn joinCol : columns) {
+ Column synthCol = (Column) columnIterator.next();
+ if ( joinCol.isNameDeferred() ) {
+ //this has to be the default value
+ joinCol.linkValueUsingDefaultColumnNaming( synthCol, referencedEntity, value );
+ }
+ else {
+ joinCol.linkWithValue( value );
+ joinCol.overrideFromReferencedColumnIfNecessary( synthCol );
+ }
+ }
+ }
+
+ public static void createUniqueConstraint(Value value) {
+ Iterator iter = value.getColumnIterator();
+ ArrayList cols = new ArrayList();
+ while ( iter.hasNext() ) {
+ cols.add( iter.next() );
+ }
+ value.getTable().createUniqueKey( cols );
+ }
+
+ public static void addIndexes(Table hibTable, Index[] indexes, ExtendedMappings
mappings) {
+ for (Index index : indexes) {
+ //no need to handle inSecondPass here since it is only called from EntityBinder
+ mappings.addSecondPass(
+ new IndexOrUniqueKeySecondPass( hibTable, index.name(), index.columnNames(),
mappings )
+ );
+ }
+ }
+
+ /**
+ * @deprecated Use {@link #buildUniqueConstraintHolders} instead
+ */
+ @SuppressWarnings({ "JavaDoc" })
+ public static List<String[]> buildUniqueConstraints(UniqueConstraint[]
constraintsArray) {
+ List<String[]> result = new ArrayList<String[]>();
+ if ( constraintsArray.length != 0 ) {
+ for (UniqueConstraint uc : constraintsArray) {
+ result.add( uc.columnNames() );
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Build a list of {@link org.hibernate.cfg.UniqueConstraintHolder} instances given a
list of
+ * {@link UniqueConstraint} annotations.
+ *
+ * @param annotations The {@link UniqueConstraint} annotations.
+ *
+ * @return The built {@link org.hibernate.cfg.UniqueConstraintHolder} instances.
+ */
+ public static List<UniqueConstraintHolder>
buildUniqueConstraintHolders(UniqueConstraint[] annotations) {
+ List<UniqueConstraintHolder> result;
+ if ( annotations == null || annotations.length == 0 ) {
+ result = java.util.Collections.emptyList();
+ }
+ else {
+ result = new ArrayList<UniqueConstraintHolder>(
CollectionHelper.determineProperSizing( annotations.length ) );
+ for ( UniqueConstraint uc : annotations ) {
+ result.add(
+ new UniqueConstraintHolder()
+ .setName( uc.name() )
+ .setColumns( uc.columnNames() )
+ );
+ }
+ }
+ return result;
+ }
+
+ public void setDefaultName(
+ String ownerEntity, String ownerEntityTable, String associatedEntity, String
associatedEntityTable,
+ String propertyName
+ ) {
+ this.ownerEntity = ownerEntity;
+ this.ownerEntityTable = ownerEntityTable;
+ this.associatedEntity = associatedEntity;
+ this.associatedEntityTable = associatedEntityTable;
+ this.propertyName = propertyName;
+ this.name = null;
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/TableBinder.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/cfg/annotations/Version.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/Version.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/annotations/Version.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/annotations/Version.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,39 @@
+// $Id$
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg.annotations;
+
+/**
+ * @author Emmanuel Bernard
+ * @deprecated Use {@link org.hibernate.Version} instead
+ */
+@Deprecated
+public class Version {
+ public static String getVersionString() {
+ return org.hibernate.Version.getVersionString();
+ }
+
+ public static void touch() {
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/Version.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/reflection/JPAMetadataProvider.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/JPAMetadataProvider.java)
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/reflection/JPAMetadataProvider.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/reflection/JPAMetadataProvider.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,128 @@
+package org.hibernate.cfg.annotations.reflection;
+
+import java.lang.reflect.AnnotatedElement;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.persistence.EntityListeners;
+import javax.persistence.NamedNativeQuery;
+import javax.persistence.NamedQuery;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.SqlResultSetMapping;
+import javax.persistence.TableGenerator;
+
+import org.dom4j.Element;
+
+import org.hibernate.annotations.common.reflection.AnnotationReader;
+import org.hibernate.annotations.common.reflection.MetadataProvider;
+import org.hibernate.annotations.common.reflection.java.JavaMetadataProvider;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * MetadataProvider aware of the JPA Deployment descriptor
+ *
+ * @author Emmanuel Bernard
+ */
+public class JPAMetadataProvider implements MetadataProvider {
+ private MetadataProvider delegate = new JavaMetadataProvider();
+ private XMLContext xmlContext = new XMLContext();
+ private Map<Object, Object> defaults;
+ private Map<AnnotatedElement, AnnotationReader> cache = new
HashMap<AnnotatedElement, AnnotationReader>(100);
+
+ public AnnotationReader getAnnotationReader(AnnotatedElement annotatedElement) {
+ AnnotationReader reader = cache.get( annotatedElement );
+ if (reader == null) {
+ if ( xmlContext.hasContext() ) {
+ reader = new JPAOverridenAnnotationReader( annotatedElement, xmlContext );
+ }
+ else {
+ reader = delegate.getAnnotationReader( annotatedElement );
+ }
+ cache.put(annotatedElement, reader);
+ }
+ return reader;
+ }
+
+ public Map<Object, Object> getDefaults() {
+ if ( defaults == null ) {
+ defaults = new HashMap<Object, Object>();
+ XMLContext.Default xmlDefaults = xmlContext.getDefault( null );
+
+ defaults.put( "delimited-identifier", xmlDefaults.getDelimitedIdentifier()
);
+ List<Class> entityListeners = new ArrayList<Class>();
+ for ( String className : xmlContext.getDefaultEntityListeners() ) {
+ try {
+ entityListeners.add( ReflectHelper.classForName( className, this.getClass() ) );
+ }
+ catch ( ClassNotFoundException e ) {
+ throw new IllegalStateException( "Default entity listener class not found:
" + className );
+ }
+ }
+ defaults.put( EntityListeners.class, entityListeners );
+ for ( Element element : xmlContext.getAllDocuments() ) {
+ @SuppressWarnings( "unchecked" )
+ List<Element> elements = element.elements( "sequence-generator" );
+ List<SequenceGenerator> sequenceGenerators = ( List<SequenceGenerator> )
defaults.get( SequenceGenerator.class );
+ if ( sequenceGenerators == null ) {
+ sequenceGenerators = new ArrayList<SequenceGenerator>();
+ defaults.put( SequenceGenerator.class, sequenceGenerators );
+ }
+ for ( Element subelement : elements ) {
+ sequenceGenerators.add(
JPAOverridenAnnotationReader.buildSequenceGeneratorAnnotation( subelement ) );
+ }
+
+ elements = element.elements( "table-generator" );
+ List<TableGenerator> tableGenerators = ( List<TableGenerator> )
defaults.get( TableGenerator.class );
+ if ( tableGenerators == null ) {
+ tableGenerators = new ArrayList<TableGenerator>();
+ defaults.put( TableGenerator.class, tableGenerators );
+ }
+ for ( Element subelement : elements ) {
+ tableGenerators.add(
+ JPAOverridenAnnotationReader.buildTableGeneratorAnnotation(
+ subelement, xmlDefaults
+ )
+ );
+ }
+
+ List<NamedQuery> namedQueries = ( List<NamedQuery> ) defaults.get(
NamedQuery.class );
+ if ( namedQueries == null ) {
+ namedQueries = new ArrayList<NamedQuery>();
+ defaults.put( NamedQuery.class, namedQueries );
+ }
+ List<NamedQuery> currentNamedQueries =
JPAOverridenAnnotationReader.buildNamedQueries(
+ element, false, xmlDefaults
+ );
+ namedQueries.addAll( currentNamedQueries );
+
+ List<NamedNativeQuery> namedNativeQueries = ( List<NamedNativeQuery> )
defaults.get( NamedNativeQuery.class );
+ if ( namedNativeQueries == null ) {
+ namedNativeQueries = new ArrayList<NamedNativeQuery>();
+ defaults.put( NamedNativeQuery.class, namedNativeQueries );
+ }
+ List<NamedNativeQuery> currentNamedNativeQueries =
JPAOverridenAnnotationReader.buildNamedQueries(
+ element, true, xmlDefaults
+ );
+ namedNativeQueries.addAll( currentNamedNativeQueries );
+
+ List<SqlResultSetMapping> sqlResultSetMappings = (
List<SqlResultSetMapping> ) defaults.get(
+ SqlResultSetMapping.class
+ );
+ if ( sqlResultSetMappings == null ) {
+ sqlResultSetMappings = new ArrayList<SqlResultSetMapping>();
+ defaults.put( SqlResultSetMapping.class, sqlResultSetMappings );
+ }
+ List<SqlResultSetMapping> currentSqlResultSetMappings =
JPAOverridenAnnotationReader.buildSqlResultsetMappings(
+ element, xmlDefaults
+ );
+ sqlResultSetMappings.addAll( currentSqlResultSetMappings );
+ }
+ }
+ return defaults;
+ }
+
+ public XMLContext getXMLContext() {
+ return xmlContext;
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/reflection/JPAMetadataProvider.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/reflection/JPAOverridenAnnotationReader.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/JPAOverridenAnnotationReader.java)
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/reflection/JPAOverridenAnnotationReader.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/reflection/JPAOverridenAnnotationReader.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,2177 @@
+// $Id$
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg.annotations.reflection;
+
+import java.beans.Introspector;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.persistence.Access;
+import javax.persistence.AccessType;
+import javax.persistence.AssociationOverride;
+import javax.persistence.AssociationOverrides;
+import javax.persistence.AttributeOverride;
+import javax.persistence.AttributeOverrides;
+import javax.persistence.Basic;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.ColumnResult;
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.DiscriminatorType;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Embeddable;
+import javax.persistence.Embedded;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.EntityListeners;
+import javax.persistence.EntityResult;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.ExcludeDefaultListeners;
+import javax.persistence.ExcludeSuperclassListeners;
+import javax.persistence.FetchType;
+import javax.persistence.FieldResult;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinColumns;
+import javax.persistence.JoinTable;
+import javax.persistence.Lob;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.MapKey;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.NamedNativeQueries;
+import javax.persistence.NamedNativeQuery;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.OrderBy;
+import javax.persistence.PostLoad;
+import javax.persistence.PostPersist;
+import javax.persistence.PostRemove;
+import javax.persistence.PostUpdate;
+import javax.persistence.PrePersist;
+import javax.persistence.PreRemove;
+import javax.persistence.PreUpdate;
+import javax.persistence.PrimaryKeyJoinColumn;
+import javax.persistence.PrimaryKeyJoinColumns;
+import javax.persistence.QueryHint;
+import javax.persistence.SecondaryTable;
+import javax.persistence.SecondaryTables;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.SqlResultSetMapping;
+import javax.persistence.SqlResultSetMappings;
+import javax.persistence.Table;
+import javax.persistence.TableGenerator;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.persistence.Transient;
+import javax.persistence.UniqueConstraint;
+import javax.persistence.Version;
+import javax.persistence.ElementCollection;
+
+import org.dom4j.Attribute;
+import org.dom4j.Element;
+import org.hibernate.AnnotationException;
+import org.hibernate.annotations.CollectionOfElements;
+import org.hibernate.annotations.Columns;
+import org.hibernate.annotations.common.annotationfactory.AnnotationDescriptor;
+import org.hibernate.annotations.common.annotationfactory.AnnotationFactory;
+import org.hibernate.annotations.common.reflection.AnnotationReader;
+import org.hibernate.annotations.common.reflection.Filter;
+import org.hibernate.annotations.common.reflection.ReflectionUtil;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.StringHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Encapsulates the overriding of Java annotations from an EJB 3.0 descriptor.
+ *
+ * @author Paolo Perrotta
+ * @author Davide Marchignoli
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+@SuppressWarnings("unchecked")
+public class JPAOverridenAnnotationReader implements AnnotationReader {
+ private Logger log = LoggerFactory.getLogger( JPAOverridenAnnotationReader.class );
+ private static final Map<Class, String> annotationToXml;
+ private static final String SCHEMA_VALIDATION = "Activate schema validation for
more information";
+ private static final Filter FILTER = new Filter() {
+ public boolean returnStatic() {
+ return false;
+ }
+
+ public boolean returnTransient() {
+ return false;
+ }
+ };
+
+ static {
+ annotationToXml = new HashMap<Class, String>();
+ annotationToXml.put( Entity.class, "entity" );
+ annotationToXml.put( MappedSuperclass.class, "mapped-superclass" );
+ annotationToXml.put( Embeddable.class, "embeddable" );
+ annotationToXml.put( Table.class, "table" );
+ annotationToXml.put( SecondaryTable.class, "secondary-table" );
+ annotationToXml.put( SecondaryTables.class, "secondary-table" );
+ annotationToXml.put( PrimaryKeyJoinColumn.class, "primary-key-join-column"
);
+ annotationToXml.put( PrimaryKeyJoinColumns.class, "primary-key-join-column"
);
+ annotationToXml.put( IdClass.class, "id-class" );
+ annotationToXml.put( Inheritance.class, "inheritance" );
+ annotationToXml.put( DiscriminatorValue.class, "discriminator-value" );
+ annotationToXml.put( DiscriminatorColumn.class, "discriminator-column" );
+ annotationToXml.put( SequenceGenerator.class, "sequence-generator" );
+ annotationToXml.put( TableGenerator.class, "table-generator" );
+ annotationToXml.put( NamedQuery.class, "named-query" );
+ annotationToXml.put( NamedQueries.class, "named-query" );
+ annotationToXml.put( NamedNativeQuery.class, "named-native-query" );
+ annotationToXml.put( NamedNativeQueries.class, "named-native-query" );
+ annotationToXml.put( SqlResultSetMapping.class, "sql-result-set-mapping" );
+ annotationToXml.put( SqlResultSetMappings.class, "sql-result-set-mapping" );
+ annotationToXml.put( ExcludeDefaultListeners.class,
"exclude-default-listeners" );
+ annotationToXml.put( ExcludeSuperclassListeners.class,
"exclude-superclass-listeners" );
+ annotationToXml.put( AccessType.class, "access" );
+ annotationToXml.put( AttributeOverride.class, "attribute-override" );
+ annotationToXml.put( AttributeOverrides.class, "attribute-override" );
+ annotationToXml.put( AttributeOverride.class, "association-override" );
+ annotationToXml.put( AttributeOverrides.class, "association-override" );
+ annotationToXml.put( Id.class, "id" );
+ annotationToXml.put( EmbeddedId.class, "embedded-id" );
+ annotationToXml.put( GeneratedValue.class, "generated-value" );
+ annotationToXml.put( Column.class, "column" );
+ annotationToXml.put( Columns.class, "column" );
+ annotationToXml.put( Temporal.class, "temporal" );
+ annotationToXml.put( Lob.class, "lob" );
+ annotationToXml.put( Enumerated.class, "enumerated" );
+ annotationToXml.put( Version.class, "version" );
+ annotationToXml.put( Transient.class, "transient" );
+ annotationToXml.put( Basic.class, "basic" );
+ annotationToXml.put( Embedded.class, "embedded" );
+ annotationToXml.put( ManyToOne.class, "many-to-one" );
+ annotationToXml.put( OneToOne.class, "one-to-one" );
+ annotationToXml.put( OneToMany.class, "one-to-many" );
+ annotationToXml.put( ManyToMany.class, "many-to-many" );
+ annotationToXml.put( JoinTable.class, "join-table" );
+ annotationToXml.put( JoinColumn.class, "join-column" );
+ annotationToXml.put( JoinColumns.class, "join-column" );
+ annotationToXml.put( MapKey.class, "map-key" );
+ annotationToXml.put( OrderBy.class, "order-by" );
+ annotationToXml.put( EntityListeners.class, "entity-listeners" );
+ annotationToXml.put( PrePersist.class, "pre-persist" );
+ annotationToXml.put( PreRemove.class, "pre-remove" );
+ annotationToXml.put( PreUpdate.class, "pre-update" );
+ annotationToXml.put( PostPersist.class, "post-persist" );
+ annotationToXml.put( PostRemove.class, "post-remove" );
+ annotationToXml.put( PostUpdate.class, "post-update" );
+ annotationToXml.put( PostLoad.class, "post-load" );
+ }
+
+ private XMLContext xmlContext;
+ private String className;
+ private String propertyName;
+ private PropertyType propertyType;
+ private transient Annotation[] annotations;
+ private transient Map<Class, Annotation> annotationsMap;
+ private static final String WORD_SEPARATOR = "-";
+ private transient List<Element> elementsForProperty;
+ private AccessibleObject mirroredAttribute;
+ private final AnnotatedElement element;
+
+ private enum PropertyType {
+ PROPERTY,
+ FIELD,
+ METHOD
+ }
+
+ public JPAOverridenAnnotationReader(AnnotatedElement el, XMLContext xmlContext) {
+ this.element = el;
+ this.xmlContext = xmlContext;
+ if ( el instanceof Class ) {
+ Class clazz = (Class) el;
+ className = clazz.getName();
+ }
+ else if ( el instanceof Field ) {
+ Field field = (Field) el;
+ className = field.getDeclaringClass().getName();
+ propertyName = field.getName();
+ propertyType = PropertyType.FIELD;
+ String expectedGetter = "get" + Character.toUpperCase( propertyName.charAt(
0 ) ) + propertyName.substring(
+ 1
+ );
+ try {
+ mirroredAttribute = field.getDeclaringClass().getDeclaredMethod( expectedGetter );
+ }
+ catch (NoSuchMethodException e) {
+ //no method
+ }
+ }
+ else if ( el instanceof Method ) {
+ Method method = (Method) el;
+ className = method.getDeclaringClass().getName();
+ propertyName = method.getName();
+ if ( ReflectionUtil.isProperty(
+ method,
+ null, //this is yukky!! we'd rather get the TypeEnvironment()
+ FILTER
+ ) ) {
+ if ( propertyName.startsWith( "get" ) ) {
+ propertyName = Introspector.decapitalize( propertyName.substring(
"get".length() ) );
+ }
+ else if ( propertyName.startsWith( "is" ) ) {
+ propertyName = Introspector.decapitalize( propertyName.substring(
"is".length() ) );
+ }
+ else {
+ throw new RuntimeException( "Method " + propertyName + " is not a
property getter" );
+ }
+ propertyType = PropertyType.PROPERTY;
+ try {
+ mirroredAttribute = method.getDeclaringClass().getDeclaredField( propertyName );
+ }
+ catch (NoSuchFieldException e) {
+ //no method
+ }
+ }
+ else {
+ propertyType = PropertyType.METHOD;
+ }
+ }
+ else {
+ className = null;
+ propertyName = null;
+ }
+ }
+
+ public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+ initAnnotations();
+ return (T) annotationsMap.get( annotationType );
+ }
+
+ public <T extends Annotation> boolean isAnnotationPresent(Class<T>
annotationType) {
+ initAnnotations();
+ return (T) annotationsMap.get( annotationType ) != null;
+ }
+
+ public Annotation[] getAnnotations() {
+ initAnnotations();
+ return annotations;
+ }
+
+ /*
+ * The idea is to create annotation proxies for the xml configuration elements. Using
this proxy annotations together
+ * with the {@code JPAMetadataprovider} allows to handle xml configuration the same way
as annotation configuration.
+ */
+ private void initAnnotations() {
+ if ( annotations == null ) {
+ XMLContext.Default defaults = xmlContext.getDefault( className );
+ if ( className != null && propertyName == null ) {
+ //is a class
+ Element tree = xmlContext.getXMLTree( className );
+ Annotation[] annotations = getJavaAnnotations();
+ List<Annotation> annotationList = new ArrayList<Annotation>(
annotations.length + 5 );
+ annotationsMap = new HashMap<Class, Annotation>( annotations.length + 5 );
+ for (Annotation annotation : annotations) {
+ if ( !annotationToXml.containsKey( annotation.annotationType() ) ) {
+ //unknown annotations are left over
+ annotationList.add( annotation );
+ }
+ }
+ addIfNotNull( annotationList, getEntity( tree, defaults ) );
+ addIfNotNull( annotationList, getMappedSuperclass( tree, defaults ) );
+ addIfNotNull( annotationList, getEmbeddable( tree, defaults ) );
+ addIfNotNull( annotationList, getTable( tree, defaults ) );
+ addIfNotNull( annotationList, getSecondaryTables( tree, defaults ) );
+ addIfNotNull( annotationList, getPrimaryKeyJoinColumns( tree, defaults ) );
+ addIfNotNull( annotationList, getIdClass( tree, defaults ) );
+ addIfNotNull( annotationList, getInheritance( tree, defaults ) );
+ addIfNotNull( annotationList, getDiscriminatorValue( tree, defaults ) );
+ addIfNotNull( annotationList, getDiscriminatorColumn( tree, defaults ) );
+ addIfNotNull( annotationList, getSequenceGenerator( tree, defaults ) );
+ addIfNotNull( annotationList, getTableGenerator( tree, defaults ) );
+ addIfNotNull( annotationList, getNamedQueries( tree, defaults ) );
+ addIfNotNull( annotationList, getNamedNativeQueries( tree, defaults ) );
+ addIfNotNull( annotationList, getSqlResultSetMappings( tree, defaults ) );
+ addIfNotNull( annotationList, getExcludeDefaultListeners( tree, defaults ) );
+ addIfNotNull( annotationList, getExcludeSuperclassListeners( tree, defaults ) );
+ addIfNotNull( annotationList, getAccessType( tree, defaults ) );
+ addIfNotNull( annotationList, getAttributeOverrides( tree, defaults ) );
+ addIfNotNull( annotationList, getAssociationOverrides( tree, defaults ) );
+ addIfNotNull( annotationList, getEntityListeners( tree, defaults ) );
+ //FIXME use annotationsMap rather than annotationList this will be faster since the
annotation type is usually known at put() time
+ this.annotations = annotationList.toArray( new Annotation[annotationList.size()] );
+ for (Annotation ann : this.annotations) {
+ annotationsMap.put( ann.annotationType(), ann );
+ }
+ checkForOrphanProperties( tree );
+ }
+ else if ( className != null ) { //&& propertyName != null ) { //always true
but less confusing
+ Element tree = xmlContext.getXMLTree( className );
+ Annotation[] annotations = getJavaAnnotations();
+ List<Annotation> annotationList = new ArrayList<Annotation>(
annotations.length + 5 );
+ annotationsMap = new HashMap<Class, Annotation>( annotations.length + 5 );
+ for (Annotation annotation : annotations) {
+ if ( !annotationToXml.containsKey( annotation.annotationType() ) ) {
+ //unknown annotations are left over
+ annotationList.add( annotation );
+ }
+ }
+ preCalculateElementsForProperty( tree );
+ Transient transientAnn = getTransient( defaults );
+ if ( transientAnn != null ) {
+ annotationList.add( transientAnn );
+ }
+ else {
+ if ( defaults.canUseJavaAnnotations() ) {
+ Annotation annotation = getJavaAnnotation( Access.class );
+ addIfNotNull( annotationList, annotation );
+ }
+ getId( annotationList, defaults );
+ getEmbeddedId( annotationList, defaults );
+ getEmbedded( annotationList, defaults );
+ getBasic( annotationList, defaults );
+ getVersion( annotationList, defaults );
+ getAssociation( ManyToOne.class, annotationList, defaults );
+ getAssociation( OneToOne.class, annotationList, defaults );
+ getAssociation( OneToMany.class, annotationList, defaults );
+ getAssociation( ManyToMany.class, annotationList, defaults );
+ getElementCollection( annotationList, defaults );
+ addIfNotNull( annotationList, getSequenceGenerator( elementsForProperty, defaults )
);
+ addIfNotNull( annotationList, getTableGenerator( elementsForProperty, defaults ) );
+ addIfNotNull( annotationList, getAttributeOverrides( elementsForProperty, defaults )
);
+
+ }
+ processEventAnnotations( annotationList, defaults );
+ //FIXME use annotationsMap rather than annotationList this will be faster since the
annotation type is usually known at put() time
+ this.annotations = annotationList.toArray( new Annotation[annotationList.size()] );
+ for (Annotation ann : this.annotations) {
+ annotationsMap.put( ann.annotationType(), ann );
+ }
+ }
+ else {
+ this.annotations = getJavaAnnotations();
+ annotationsMap = new HashMap<Class, Annotation>( annotations.length + 5 );
+ for (Annotation ann : this.annotations) {
+ annotationsMap.put( ann.annotationType(), ann );
+ }
+ }
+ }
+ }
+
+ private void checkForOrphanProperties(Element tree) {
+ Class clazz;
+ try {
+ clazz = ReflectHelper.classForName( className, this.getClass() );
+ }
+ catch (ClassNotFoundException e) {
+ return; //a primitive type most likely
+ }
+ Element element = tree != null ? tree.element( "attributes" ) : null;
+ //put entity.attributes elements
+ if ( element != null ) {
+ //precompute the list of properties
+ //TODO is it really useful...
+ Set<String> properties = new HashSet<String>();
+ for (Field field : clazz.getFields()) {
+ properties.add( field.getName() );
+ }
+ for (Method method : clazz.getMethods()) {
+ String name = method.getName();
+ if ( name.startsWith( "get" ) ) {
+ properties.add( Introspector.decapitalize( name.substring( "get".length()
) ) );
+ }
+ else if ( name.startsWith( "is" ) ) {
+ properties.add( Introspector.decapitalize( name.substring( "is".length() )
) );
+ }
+ }
+ for (Element subelement : (List<Element>) element.elements()) {
+ String propertyName = subelement.attributeValue( "name" );
+ if ( !properties.contains( propertyName ) ) {
+ log.warn( "Property {} not found in class"
+ + " but described in <mapping-file/> (possible typo error)",
+ StringHelper.qualify( className, propertyName ) );
+ }
+ }
+ }
+ }
+
+ /**
+ * Adds {@code annotation} to the list (only if it's not null) and then returns it.
+ *
+ * @param annotationList The list of annotations.
+ * @param annotation The annotation to add to the list.
+ *
+ * @return The annotation which was added to the list or {@code null}.
+ */
+ private Annotation addIfNotNull(List<Annotation> annotationList, Annotation
annotation) {
+ if ( annotation != null ) {
+ annotationList.add( annotation );
+ }
+ return annotation;
+ }
+
+ //TODO mutualize the next 2 methods
+ private Annotation getTableGenerator(List<Element> elementsForProperty,
XMLContext.Default defaults) {
+ for (Element element : elementsForProperty) {
+ Element subelement = element != null ? element.element( annotationToXml.get(
TableGenerator.class ) ) : null;
+ if ( subelement != null ) {
+ return buildTableGeneratorAnnotation( subelement, defaults );
+ }
+ }
+ if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( TableGenerator.class );
+ }
+ else {
+ return null;
+ }
+ }
+
+
+ private Annotation getSequenceGenerator(List<Element> elementsForProperty,
XMLContext.Default defaults) {
+ for (Element element : elementsForProperty) {
+ Element subelement = element != null ? element.element( annotationToXml.get(
SequenceGenerator.class ) ) : null;
+ if ( subelement != null ) {
+ return buildSequenceGeneratorAnnotation( subelement );
+ }
+ }
+ if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( SequenceGenerator.class );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private void processEventAnnotations(List<Annotation> annotationList,
XMLContext.Default defaults) {
+ boolean eventElement = false;
+ for (Element element : elementsForProperty) {
+ String elementName = element.getName();
+ if ( "pre-persist".equals( elementName ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( PrePersist.class );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ eventElement = true;
+ }
+ else if ( "pre-remove".equals( elementName ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( PreRemove.class );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ eventElement = true;
+ }
+ else if ( "pre-update".equals( elementName ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( PreUpdate.class );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ eventElement = true;
+ }
+ else if ( "post-persist".equals( elementName ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( PostPersist.class );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ eventElement = true;
+ }
+ else if ( "post-remove".equals( elementName ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( PostRemove.class );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ eventElement = true;
+ }
+ else if ( "post-update".equals( elementName ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( PostUpdate.class );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ eventElement = true;
+ }
+ else if ( "post-load".equals( elementName ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( PostLoad.class );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ eventElement = true;
+ }
+ }
+ if ( !eventElement && defaults.canUseJavaAnnotations() ) {
+ Annotation ann = getJavaAnnotation( PrePersist.class );
+ addIfNotNull( annotationList, ann );
+ ann = getJavaAnnotation( PreRemove.class );
+ addIfNotNull( annotationList, ann );
+ ann = getJavaAnnotation( PreUpdate.class );
+ addIfNotNull( annotationList, ann );
+ ann = getJavaAnnotation( PostPersist.class );
+ addIfNotNull( annotationList, ann );
+ ann = getJavaAnnotation( PostRemove.class );
+ addIfNotNull( annotationList, ann );
+ ann = getJavaAnnotation( PostUpdate.class );
+ addIfNotNull( annotationList, ann );
+ ann = getJavaAnnotation( PostLoad.class );
+ addIfNotNull( annotationList, ann );
+ }
+ }
+
+ private EntityListeners getEntityListeners(Element tree, XMLContext.Default defaults) {
+ Element element = tree != null ? tree.element( "entity-listeners" ) : null;
+ if ( element != null ) {
+ List<Class> entityListenerClasses = new ArrayList<Class>();
+ for (Element subelement : (List<Element>) element.elements(
"entity-listener" )) {
+ String className = subelement.attributeValue( "class" );
+ try {
+ entityListenerClasses.add(
+ ReflectHelper.classForName(
+ XMLContext.buildSafeClassName( className, defaults ),
+ this.getClass()
+ )
+ );
+ }
+ catch (ClassNotFoundException e) {
+ throw new AnnotationException(
+ "Unable to find " + element.getPath() + ".class: " +
className, e
+ );
+ }
+ }
+ AnnotationDescriptor ad = new AnnotationDescriptor( EntityListeners.class );
+ ad.setValue( "value", entityListenerClasses.toArray( new
Class[entityListenerClasses.size()] ) );
+ return AnnotationFactory.create( ad );
+ }
+ else if ( defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( EntityListeners.class );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private JoinTable overridesDefaultsInJoinTable(Annotation annotation, XMLContext.Default
defaults) {
+ //no element but might have some default or some annotation
+ boolean defaultToJoinTable = !( isJavaAnnotationPresent( JoinColumn.class )
+ || isJavaAnnotationPresent( JoinColumns.class ) );
+ final Class<? extends Annotation> annotationClass = annotation.annotationType();
+ defaultToJoinTable = defaultToJoinTable &&
+ ( ( annotationClass == ManyToMany.class && StringHelper.isEmpty( (
(ManyToMany) annotation ).mappedBy() ) )
+ || ( annotationClass == OneToMany.class && StringHelper.isEmpty( (
(OneToMany) annotation ).mappedBy() ) )
+ || ( annotationClass == CollectionOfElements.class ) //legacy Hibernate
+ || ( annotationClass == ElementCollection.class )
+ );
+ final Class<JoinTable> annotationType = JoinTable.class;
+ if ( defaultToJoinTable
+ && ( StringHelper.isNotEmpty( defaults.getCatalog() )
+ || StringHelper.isNotEmpty( defaults.getSchema() ) ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( annotationType );
+ if ( defaults.canUseJavaAnnotations() ) {
+ JoinTable table = getJavaAnnotation( annotationType );
+ if ( table != null ) {
+ ad.setValue( "name", table.name() );
+ ad.setValue( "schema", table.schema() );
+ ad.setValue( "catalog", table.catalog() );
+ ad.setValue( "uniqueConstraints", table.uniqueConstraints() );
+ ad.setValue( "joinColumns", table.joinColumns() );
+ ad.setValue( "inverseJoinColumns", table.inverseJoinColumns() );
+ }
+ }
+ if ( StringHelper.isEmpty( (String) ad.valueOf( "schema" ) )
+ && StringHelper.isNotEmpty( defaults.getSchema() ) ) {
+ ad.setValue( "schema", defaults.getSchema() );
+ }
+ if ( StringHelper.isEmpty( (String) ad.valueOf( "catalog" ) )
+ && StringHelper.isNotEmpty( defaults.getCatalog() ) ) {
+ ad.setValue( "catalog", defaults.getCatalog() );
+ }
+ return AnnotationFactory.create( ad );
+ }
+ else if ( defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( annotationType );
+ }
+ else {
+ return null;
+ }
+ }
+
+ /*
+ * no partial overriding possible
+ */
+ private void getJoinTable(List<Annotation> annotationList, Element tree,
XMLContext.Default defaults) {
+ Element subelement = tree == null ? null : tree.element( "join-table" );
+ final Class<JoinTable> annotationType = JoinTable.class;
+ if ( subelement != null ) {
+ //ignore java annotation, an element is defined
+ AnnotationDescriptor annotation = new AnnotationDescriptor( annotationType );
+ 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() );
+ }
+ buildUniqueConstraints( annotation, subelement );
+ annotation.setValue( "joinColumns", getJoinColumns( subelement, false ) );
+ annotation.setValue( "inverseJoinColumns", getJoinColumns( subelement, true
) );
+ annotationList.add( AnnotationFactory.create( annotation ) );
+ }
+ }
+
+ private void getAssociation(
+ Class<? extends Annotation> annotationType, List<Annotation>
annotationList, XMLContext.Default defaults
+ ) {
+ String xmlName = annotationToXml.get( annotationType );
+ for (Element element : elementsForProperty) {
+ if ( xmlName.equals( element.getName() ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( annotationType );
+ addTargetClass( element, ad, "target-entity", defaults );
+ getFetchType( ad, element );
+ getCascades( ad, element, defaults );
+ getJoinTable( annotationList, element, defaults );
+ buildJoinColumns( annotationList, element);
+ Annotation annotation = getPrimaryKeyJoinColumns( element, defaults );
+ addIfNotNull( annotationList, annotation );
+ copyBooleanAttribute( ad, element, "optional" );
+ copyStringAttribute( ad, element, "mapped-by", false );
+ getOrderBy( annotationList, element );
+ getMapKey( annotationList, element );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ getAccessType( annotationList, element );
+ }
+ }
+ if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
+ Annotation annotation = getJavaAnnotation( annotationType );
+ if ( annotation != null ) {
+ annotationList.add( annotation );
+ annotation = overridesDefaultsInJoinTable( annotation, defaults );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( JoinColumn.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( JoinColumns.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( PrimaryKeyJoinColumn.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( PrimaryKeyJoinColumns.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( MapKey.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( OrderBy.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Lob.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 );
+ }
+ else if ( isJavaAnnotationPresent( ElementCollection.class ) ) { //JPA2
+ annotation = overridesDefaultsInJoinTable( getJavaAnnotation( ElementCollection.class
), defaults );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( JoinColumn.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( JoinColumns.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( PrimaryKeyJoinColumn.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( PrimaryKeyJoinColumns.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( MapKey.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( OrderBy.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Lob.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 );
+ }
+ else if ( isJavaAnnotationPresent( CollectionOfElements.class ) ) { //legacy
Hibernate
+ annotation = overridesDefaultsInJoinTable( getJavaAnnotation(
CollectionOfElements.class ), defaults );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( JoinColumn.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( JoinColumns.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( PrimaryKeyJoinColumn.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( PrimaryKeyJoinColumns.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( MapKey.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( OrderBy.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Lob.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 );
+ }
+ }
+ }
+
+ private void addTargetClass(Element element, AnnotationDescriptor ad, String nodeName,
XMLContext.Default defaults) {
+ String className = element.attributeValue( nodeName );
+ if ( className != null ) {
+ Class clazz;
+ try {
+ clazz = ReflectHelper.classForName(
+ XMLContext.buildSafeClassName( className, defaults ),
+ this.getClass()
+ );
+ }
+ catch (ClassNotFoundException e) {
+ throw new AnnotationException(
+ "Unable to find " + element.getPath() + " " + nodeName +
": " + className, e
+ );
+ }
+ ad.setValue( getJavaAttributeNameFromXMLOne(nodeName), clazz );
+ }
+ }
+
+ // TODO: Complete parsing of all element-collection related xml
+ private void getElementCollection(List<Annotation> annotationList,
XMLContext.Default defaults) {
+ for ( Element element : elementsForProperty ) {
+ if ( "element-collection".equals( element.getName() ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( ElementCollection.class );
+ addTargetClass( element, ad, "target-class", defaults );
+ annotationList.add( AnnotationFactory.create( ad ) );
+
+ getAccessType( annotationList, element );
+ }
+ }
+ }
+
+ private void getOrderBy(List<Annotation> annotationList, Element element) {
+ Element subelement = element != null ? element.element( "order-by" ) : null;
+ if ( subelement != null ) {
+ String orderByString = subelement.getTextTrim();
+ AnnotationDescriptor ad = new AnnotationDescriptor( OrderBy.class );
+ if ( StringHelper.isNotEmpty( orderByString ) ) ad.setValue( "value",
orderByString );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ }
+ }
+
+ private void getMapKey(List<Annotation> annotationList, Element element) {
+ Element subelement = element != null ? element.element( "map-key" ) : null;
+ if ( subelement != null ) {
+ String mapKeyString = subelement.attributeValue( "name" );
+ AnnotationDescriptor ad = new AnnotationDescriptor( MapKey.class );
+ if ( StringHelper.isNotEmpty( mapKeyString ) ) ad.setValue( "name",
mapKeyString );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ }
+ }
+
+ private void buildJoinColumns(List<Annotation> annotationList, Element element) {
+ JoinColumn[] joinColumns = getJoinColumns( element, false );
+ if ( joinColumns.length > 0 ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( JoinColumns.class );
+ ad.setValue( "value", joinColumns );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ }
+ }
+
+ private void getCascades(AnnotationDescriptor ad, Element element, XMLContext.Default
defaults) {
+ List<Element> elements = element != null ? element.elements( "cascade"
) : new ArrayList<Element>( 0 );
+ List<CascadeType> cascades = new ArrayList<CascadeType>();
+ for (Element subelement : elements) {
+ if ( subelement.element( "cascade-all" ) != null ) cascades.add(
CascadeType.ALL );
+ if ( subelement.element( "cascade-persist" ) != null ) cascades.add(
CascadeType.PERSIST );
+ if ( subelement.element( "cascade-merge" ) != null ) cascades.add(
CascadeType.MERGE );
+ if ( subelement.element( "cascade-remove" ) != null ) cascades.add(
CascadeType.REMOVE );
+ if ( subelement.element( "cascade-refresh" ) != null ) cascades.add(
CascadeType.REFRESH );
+ if ( subelement.element( "cascade-detach" ) != null ) cascades.add(
CascadeType.DETACH );
+ }
+ if ( Boolean.TRUE.equals( defaults.getCascadePersist() )
+ && !cascades.contains( CascadeType.ALL ) && !cascades.contains(
CascadeType.PERSIST ) ) {
+ cascades.add( CascadeType.PERSIST );
+ }
+ if ( cascades.size() > 0 ) {
+ ad.setValue( "cascade", cascades.toArray( new CascadeType[cascades.size()] )
);
+ }
+ }
+
+ private void getEmbedded(List<Annotation> annotationList, XMLContext.Default
defaults) {
+ for (Element element : elementsForProperty) {
+ if ( "embedded".equals( element.getName() ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( Embedded.class );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ getAccessType( annotationList, element );
+ }
+ }
+ if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
+ Annotation annotation = getJavaAnnotation( Embedded.class );
+ if ( annotation != null ) {
+ annotationList.add( annotation );
+ annotation = getJavaAnnotation( AttributeOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ }
+ }
+ }
+
+ private Transient getTransient(XMLContext.Default defaults) {
+ for (Element element : elementsForProperty) {
+ if ( "transient".equals( element.getName() ) ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( Transient.class );
+ return AnnotationFactory.create( ad );
+ }
+ }
+ if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( Transient.class );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private void getVersion(List<Annotation> annotationList, XMLContext.Default
defaults) {
+ for (Element element : elementsForProperty) {
+ if ( "version".equals( element.getName() ) ) {
+ Annotation annotation = buildColumns( element );
+ addIfNotNull( annotationList, annotation );
+ getTemporal( annotationList, element );
+ AnnotationDescriptor basic = new AnnotationDescriptor( Version.class );
+ annotationList.add( AnnotationFactory.create( basic ) );
+ getAccessType( annotationList, element );
+ }
+ }
+ if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
+ //we have nothing, so Java annotations might occurs
+ Annotation annotation = getJavaAnnotation( Version.class );
+ if ( annotation != null ) {
+ annotationList.add( annotation );
+ annotation = getJavaAnnotation( Column.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Columns.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Temporal.class );
+ addIfNotNull( annotationList, annotation );
+ }
+ }
+ }
+
+ private void getBasic(List<Annotation> annotationList, XMLContext.Default
defaults) {
+ for (Element element : elementsForProperty) {
+ if ( "basic".equals( element.getName() ) ) {
+ Annotation annotation = buildColumns( element );
+ addIfNotNull( annotationList, annotation );
+ getAccessType( annotationList, element );
+ getTemporal( annotationList, element );
+ getLob( annotationList, element );
+ getEnumerated( annotationList, element );
+ AnnotationDescriptor basic = new AnnotationDescriptor( Basic.class );
+ getFetchType( basic, element );
+ copyBooleanAttribute( basic, element, "optional" );
+ annotationList.add( AnnotationFactory.create( basic ) );
+ }
+ }
+ if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
+ //no annotation presence constraint, basic is the default
+ Annotation annotation = getJavaAnnotation( Basic.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Lob.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 );
+ annotation = getJavaAnnotation( AttributeOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ }
+ }
+
+ private void getEnumerated(List<Annotation> annotationList, Element element) {
+ Element subElement = element != null ? element.element( "enumerated" ) :
null;
+ if ( subElement != null ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( Enumerated.class );
+ String enumerated = subElement.getTextTrim();
+ if ( "ORDINAL".equalsIgnoreCase( enumerated ) ) {
+ ad.setValue( "value", EnumType.ORDINAL );
+ }
+ else if ( "STRING".equalsIgnoreCase( enumerated ) ) {
+ ad.setValue( "value", EnumType.STRING );
+ }
+ else if ( StringHelper.isNotEmpty( enumerated ) ) {
+ throw new AnnotationException( "Unknown EnumType: " + enumerated + ".
" + SCHEMA_VALIDATION );
+ }
+ annotationList.add( AnnotationFactory.create( ad ) );
+ }
+ }
+
+ private void getLob(List<Annotation> annotationList, Element element) {
+ Element subElement = element != null ? element.element( "lob" ) : null;
+ if ( subElement != null ) {
+ annotationList.add( AnnotationFactory.create( new AnnotationDescriptor( Lob.class ) )
);
+ }
+ }
+
+ private void getFetchType(AnnotationDescriptor descriptor, Element element) {
+ String fetchString = element != null ? element.attributeValue( "fetch" ) :
null;
+ if ( fetchString != null ) {
+ if ( "eager".equalsIgnoreCase( fetchString ) ) {
+ descriptor.setValue( "fetch", FetchType.EAGER );
+ }
+ else if ( "lazy".equalsIgnoreCase( fetchString ) ) {
+ descriptor.setValue( "fetch", FetchType.LAZY );
+ }
+ }
+ }
+
+ private void getEmbeddedId(List<Annotation> annotationList, XMLContext.Default
defaults) {
+ for (Element element : elementsForProperty) {
+ if ( "embedded-id".equals( element.getName() ) ) {
+ if ( isProcessingId( defaults ) ) {
+ Annotation annotation = getAttributeOverrides( element, defaults );
+ addIfNotNull( annotationList, annotation );
+ annotation = getAssociationOverrides( element, defaults );
+ addIfNotNull( annotationList, annotation );
+ AnnotationDescriptor ad = new AnnotationDescriptor( EmbeddedId.class );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ getAccessType( annotationList, element );
+ }
+ }
+ }
+ if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
+ Annotation annotation = getJavaAnnotation( EmbeddedId.class );
+ if ( annotation != null ) {
+ annotationList.add( annotation );
+ annotation = getJavaAnnotation( Column.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Columns.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( GeneratedValue.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Temporal.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( TableGenerator.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( SequenceGenerator.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ }
+ }
+ }
+
+ private void preCalculateElementsForProperty(Element tree) {
+ elementsForProperty = new ArrayList<Element>();
+ Element element = tree != null ? tree.element( "attributes" ) : null;
+ //put entity.attributes elements
+ if ( element != null ) {
+ for (Element subelement : (List<Element>) element.elements()) {
+ if ( propertyName.equals( subelement.attributeValue( "name" ) ) ) {
+ elementsForProperty.add( subelement );
+ }
+ }
+ }
+ //add pre-* etc from entity and pure entity listener classes
+ if ( tree != null ) {
+ for (Element subelement : (List<Element>) tree.elements()) {
+ if ( propertyName.equals( subelement.attributeValue( "method-name" ) ) ) {
+ elementsForProperty.add( subelement );
+ }
+ }
+ }
+ }
+
+ private void getId(List<Annotation> annotationList, XMLContext.Default defaults)
{
+ for (Element element : elementsForProperty) {
+ if ( "id".equals( element.getName() ) ) {
+ boolean processId = isProcessingId( defaults );
+ if ( processId ) {
+ Annotation annotation = buildColumns( element );
+ addIfNotNull( annotationList, annotation );
+ annotation = buildGeneratedValue( element );
+ addIfNotNull( annotationList, annotation );
+ getTemporal( annotationList, element );
+ //FIXME: fix the priority of xml over java for generator names
+ annotation = getTableGenerator( element, defaults );
+ addIfNotNull( annotationList, annotation );
+ annotation = getSequenceGenerator( element, defaults );
+ addIfNotNull( annotationList, annotation );
+ AnnotationDescriptor id = new AnnotationDescriptor( Id.class );
+ annotationList.add( AnnotationFactory.create( id ) );
+ getAccessType( annotationList, element );
+ }
+ }
+ }
+ if ( elementsForProperty.size() == 0 && defaults.canUseJavaAnnotations() ) {
+ Annotation annotation = getJavaAnnotation( Id.class );
+ if ( annotation != null ) {
+ annotationList.add( annotation );
+ annotation = getJavaAnnotation( Column.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Columns.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( GeneratedValue.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( Temporal.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( TableGenerator.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( SequenceGenerator.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AttributeOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverride.class );
+ addIfNotNull( annotationList, annotation );
+ annotation = getJavaAnnotation( AssociationOverrides.class );
+ addIfNotNull( annotationList, annotation );
+ }
+ }
+ }
+
+ private boolean isProcessingId(XMLContext.Default defaults) {
+ boolean isExplicit = defaults.getAccess() != null;
+ boolean correctAccess =
+ ( PropertyType.PROPERTY.equals( propertyType ) && AccessType.PROPERTY.equals(
defaults.getAccess() ) )
+ || ( PropertyType.FIELD.equals( propertyType ) && AccessType.FIELD.equals(
defaults.getAccess() ) );
+ boolean hasId = defaults.canUseJavaAnnotations()
+ && ( isJavaAnnotationPresent( Id.class ) || isJavaAnnotationPresent(
EmbeddedId.class ) );
+ //if ( properAccessOnMetadataComplete || properOverridingOnMetadataNonComplete ) {
+ boolean mirrorAttributeIsId = defaults.canUseJavaAnnotations() &&
+ ( mirroredAttribute != null &&
+ ( mirroredAttribute.isAnnotationPresent( Id.class )
+ || mirroredAttribute.isAnnotationPresent( EmbeddedId.class ) ) );
+ boolean propertyIsDefault = PropertyType.PROPERTY.equals( propertyType )
+ && !mirrorAttributeIsId;
+ return correctAccess || ( !isExplicit && hasId ) || ( !isExplicit &&
propertyIsDefault );
+ }
+
+ private Columns buildColumns(Element element) {
+ List<Element> subelements = element.elements( "column" );
+ List<Column> columns = new ArrayList<Column>( subelements.size() );
+ for (Element subelement : subelements) {
+ columns.add( getColumn( subelement, false, element ) );
+ }
+ if ( columns.size() > 0 ) {
+ AnnotationDescriptor columnsDescr = new AnnotationDescriptor( Columns.class );
+ columnsDescr.setValue( "columns", columns.toArray( new
Column[columns.size()] ) );
+ return AnnotationFactory.create( columnsDescr );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private GeneratedValue buildGeneratedValue(Element element) {
+ Element subElement = element != null ? element.element( "generated-value" ) :
null;
+ if ( subElement != null ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( GeneratedValue.class );
+ String strategy = subElement.attributeValue( "strategy" );
+ if ( "TABLE".equalsIgnoreCase( strategy ) ) {
+ ad.setValue( "strategy", GenerationType.TABLE );
+ }
+ else if ( "SEQUENCE".equalsIgnoreCase( strategy ) ) {
+ ad.setValue( "strategy", GenerationType.SEQUENCE );
+ }
+ else if ( "IDENTITY".equalsIgnoreCase( strategy ) ) {
+ ad.setValue( "strategy", GenerationType.IDENTITY );
+ }
+ else if ( "AUTO".equalsIgnoreCase( strategy ) ) {
+ ad.setValue( "strategy", GenerationType.AUTO );
+ }
+ else if ( StringHelper.isNotEmpty( strategy ) ) {
+ throw new AnnotationException( "Unknown GenerationType: " + strategy +
". " + SCHEMA_VALIDATION );
+ }
+ copyStringAttribute( ad, subElement, "generator", false );
+ return AnnotationFactory.create( ad );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private void getTemporal(List<Annotation> annotationList, Element element) {
+ Element subElement = element != null ? element.element( "temporal" ) : null;
+ if ( subElement != null ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( Temporal.class );
+ String temporal = subElement.getTextTrim();
+ if ( "DATE".equalsIgnoreCase( temporal ) ) {
+ ad.setValue( "value", TemporalType.DATE );
+ }
+ else if ( "TIME".equalsIgnoreCase( temporal ) ) {
+ ad.setValue( "value", TemporalType.TIME );
+ }
+ else if ( "TIMESTAMP".equalsIgnoreCase( temporal ) ) {
+ ad.setValue( "value", TemporalType.TIMESTAMP );
+ }
+ else if ( StringHelper.isNotEmpty( temporal ) ) {
+ throw new AnnotationException( "Unknown TemporalType: " + temporal +
". " + SCHEMA_VALIDATION );
+ }
+ annotationList.add( AnnotationFactory.create( ad ) );
+ }
+ }
+
+ private void getAccessType(List<Annotation> annotationList, Element element) {
+ if ( element == null ) {
+ return;
+ }
+ String access = element.attributeValue( "access" );
+ if ( access != null ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( Access.class );
+ AccessType type;
+ try {
+ type = AccessType.valueOf( access );
+ }
+ catch ( IllegalArgumentException e ) {
+ throw new AnnotationException( access + " is not a valid access type. Check you
xml confguration." );
+ }
+
+ if ( ( AccessType.PROPERTY.equals( type ) && this.element instanceof Method )
||
+ ( AccessType.FIELD.equals( type ) && this.element instanceof Field ) ) {
+ return;
+ }
+
+ ad.setValue( "value", type );
+ annotationList.add( AnnotationFactory.create( ad ) );
+ }
+ }
+
+ private AssociationOverrides getAssociationOverrides(Element tree, XMLContext.Default
defaults) {
+ List<AssociationOverride> attributes = (List<AssociationOverride>)
buildAssociationOverrides( tree );
+ if ( defaults.canUseJavaAnnotations() ) {
+ AssociationOverride annotation = getJavaAnnotation( AssociationOverride.class );
+ addAssociationOverrideIfNeeded( annotation, attributes );
+ AssociationOverrides annotations = getJavaAnnotation( AssociationOverrides.class );
+ if ( annotations != null ) {
+ for (AssociationOverride current : annotations.value()) {
+ addAssociationOverrideIfNeeded( current, attributes );
+ }
+ }
+ }
+ if ( attributes.size() > 0 ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( AssociationOverrides.class );
+ ad.setValue( "value", attributes.toArray( new
AssociationOverride[attributes.size()] ) );
+ return AnnotationFactory.create( ad );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private List<AssociationOverride> buildAssociationOverrides(Element element) {
+ List<Element> subelements = element == null ? null : element.elements(
"association-override" );
+ List<AssociationOverride> overrides = new
ArrayList<AssociationOverride>();
+ if ( subelements != null && subelements.size() > 0 ) {
+ for (Element current : subelements) {
+ AnnotationDescriptor override = new AnnotationDescriptor( AssociationOverride.class
);
+ copyStringAttribute( override, current, "name", true );
+ override.setValue( "joinColumns", getJoinColumns( current, false ) );
+ overrides.add( (AssociationOverride) AnnotationFactory.create( override ) );
+ }
+ }
+ return overrides;
+ }
+
+ private JoinColumn[] getJoinColumns(Element element, boolean isInverse) {
+ List<Element> subelements = element != null ?
+ element.elements( isInverse ? "inverse-join-column" :
"join-column" ) :
+ null;
+ List<JoinColumn> joinColumns = new ArrayList<JoinColumn>();
+ if ( subelements != null ) {
+ for (Element subelement : subelements) {
+ AnnotationDescriptor column = new AnnotationDescriptor( JoinColumn.class );
+ copyStringAttribute( column, subelement, "name", false );
+ copyStringAttribute( column, subelement, "referenced-column-name", false
);
+ copyBooleanAttribute( column, subelement, "unique" );
+ copyBooleanAttribute( column, subelement, "nullable" );
+ copyBooleanAttribute( column, subelement, "insertable" );
+ copyBooleanAttribute( column, subelement, "updatable" );
+ copyStringAttribute( column, subelement, "column-definition", false );
+ copyStringAttribute( column, subelement, "table", false );
+ joinColumns.add( (JoinColumn) AnnotationFactory.create( column ) );
+ }
+ }
+ return joinColumns.toArray( new JoinColumn[joinColumns.size()] );
+ }
+
+ private void addAssociationOverrideIfNeeded(AssociationOverride annotation,
List<AssociationOverride> overrides) {
+ if ( annotation != null ) {
+ String overrideName = annotation.name();
+ boolean present = false;
+ for (AssociationOverride current : overrides) {
+ if ( current.name().equals( overrideName ) ) {
+ present = true;
+ break;
+ }
+ }
+ if ( !present ) overrides.add( annotation );
+ }
+ }
+
+ private AttributeOverrides getAttributeOverrides(Element tree, XMLContext.Default
defaults) {
+ List<AttributeOverride> attributes = buildAttributeOverrides( tree );
+ return mergeAttributeOverrides( defaults, attributes );
+ }
+
+ private AttributeOverrides getAttributeOverrides(List<Element> elements,
XMLContext.Default defaults) {
+ List<AttributeOverride> attributes = new ArrayList<AttributeOverride>();
+ for (Element element : elements) {
+ attributes.addAll( buildAttributeOverrides( element ) );
+ }
+ return mergeAttributeOverrides( defaults, attributes );
+ }
+
+ private AttributeOverrides mergeAttributeOverrides(XMLContext.Default defaults,
+ List<AttributeOverride> attributes) {
+ if ( defaults.canUseJavaAnnotations() ) {
+ AttributeOverride annotation = getJavaAnnotation( AttributeOverride.class );
+ addAttributeOverrideIfNeeded( annotation, attributes );
+ AttributeOverrides annotations = getJavaAnnotation( AttributeOverrides.class );
+ if ( annotations != null ) {
+ for (AttributeOverride current : annotations.value()) {
+ addAttributeOverrideIfNeeded( current, attributes );
+ }
+ }
+ }
+ if ( attributes.size() > 0 ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( AttributeOverrides.class );
+ ad.setValue( "value", attributes.toArray( new
AttributeOverride[attributes.size()] ) );
+ return AnnotationFactory.create( ad );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private List<AttributeOverride> buildAttributeOverrides(Element element) {
+ List<Element> subelements = element == null ? null : element.elements(
"attribute-override" );
+ return buildAttributeOverrides( subelements );
+ }
+
+ private List<AttributeOverride> buildAttributeOverrides(List<Element>
subelements) {
+ List<AttributeOverride> overrides = new ArrayList<AttributeOverride>();
+ if ( subelements != null && subelements.size() > 0 ) {
+ for (Element current : subelements) {
+ if ( !current.getName().equals( "attribute-override" ) ) continue;
+ AnnotationDescriptor override = new AnnotationDescriptor( AttributeOverride.class );
+ copyStringAttribute( override, current, "name", true );
+ Element column = current.element( "column" );
+ override.setValue( "column", getColumn( column, true, current ) );
+ overrides.add( (AttributeOverride) AnnotationFactory.create( override ) );
+ }
+ }
+ return overrides;
+ }
+
+ private Column getColumn(Element element, boolean isMandatory, Element current) {
+ //Element subelement = element != null ? element.element( "column" ) : null;
+ if ( element != null ) {
+ AnnotationDescriptor column = new AnnotationDescriptor( Column.class );
+ copyStringAttribute( column, element, "name", false );
+ copyBooleanAttribute( column, element, "unique" );
+ copyBooleanAttribute( column, element, "nullable" );
+ copyBooleanAttribute( column, element, "insertable" );
+ copyBooleanAttribute( column, element, "updatable" );
+ copyStringAttribute( column, element, "column-definition", false );
+ copyStringAttribute( column, element, "table", false );
+ copyIntegerAttribute( column, element, "length" );
+ copyIntegerAttribute( column, element, "precision" );
+ copyIntegerAttribute( column, element, "scale" );
+ return (Column) AnnotationFactory.create( column );
+ }
+ else {
+ if ( isMandatory ) {
+ throw new AnnotationException( current.getPath() + ".column is mandatory. "
+ SCHEMA_VALIDATION );
+ }
+ return null;
+ }
+ }
+
+ private void addAttributeOverrideIfNeeded(AttributeOverride annotation,
List<AttributeOverride> overrides) {
+ if ( annotation != null ) {
+ String overrideName = annotation.name();
+ boolean present = false;
+ for (AttributeOverride current : overrides) {
+ if ( current.name().equals( overrideName ) ) {
+ present = true;
+ break;
+ }
+ }
+ if ( !present ) overrides.add( annotation );
+ }
+ }
+
+ private Access getAccessType(Element tree, XMLContext.Default defaults) {
+ String access = tree == null ? null : tree.attributeValue( "access" );
+ if ( access != null ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( Access.class );
+ AccessType type;
+ try {
+ type = AccessType.valueOf( access );
+ }
+ catch ( IllegalArgumentException e ) {
+ throw new AnnotationException( access + " is not a valid access type. Check you
xml confguration." );
+ }
+ ad.setValue( "value", type );
+ return AnnotationFactory.create( ad );
+ }
+ else if ( defaults.canUseJavaAnnotations() && isJavaAnnotationPresent(
Access.class ) ) {
+ return getJavaAnnotation( Access.class );
+ }
+ else if ( defaults.getAccess() != null ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( Access.class );
+ ad.setValue( "value", defaults.getAccess() );
+ return AnnotationFactory.create( ad );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private ExcludeSuperclassListeners getExcludeSuperclassListeners(Element tree,
XMLContext.Default defaults) {
+ return (ExcludeSuperclassListeners) getMarkerAnnotation(
ExcludeSuperclassListeners.class, tree, defaults );
+ }
+
+ private ExcludeDefaultListeners getExcludeDefaultListeners(Element tree,
XMLContext.Default defaults) {
+ return (ExcludeDefaultListeners) getMarkerAnnotation( ExcludeDefaultListeners.class,
tree, defaults );
+ }
+
+ private Annotation getMarkerAnnotation(
+ Class<? extends Annotation> clazz, Element element, XMLContext.Default defaults
+ ) {
+ Element subelement = element == null ? null : element.element( annotationToXml.get(
clazz ) );
+ if ( subelement != null ) {
+ return AnnotationFactory.create( new AnnotationDescriptor( clazz ) );
+ }
+ else if ( defaults.canUseJavaAnnotations() ) {
+ //TODO wonder whether it should be excluded so that user can undone it
+ return getJavaAnnotation( clazz );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private SqlResultSetMappings getSqlResultSetMappings(Element tree, XMLContext.Default
defaults) {
+ List<SqlResultSetMapping> results = (List<SqlResultSetMapping>)
buildSqlResultsetMappings( tree, defaults );
+ if ( defaults.canUseJavaAnnotations() ) {
+ SqlResultSetMapping annotation = getJavaAnnotation( SqlResultSetMapping.class );
+ addSqlResultsetMappingIfNeeded( annotation, results );
+ SqlResultSetMappings annotations = getJavaAnnotation( SqlResultSetMappings.class );
+ if ( annotations != null ) {
+ for (SqlResultSetMapping current : annotations.value()) {
+ addSqlResultsetMappingIfNeeded( current, results );
+ }
+ }
+ }
+ if ( results.size() > 0 ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( SqlResultSetMappings.class );
+ ad.setValue( "value", results.toArray( new
SqlResultSetMapping[results.size()] ) );
+ return AnnotationFactory.create( ad );
+ }
+ else {
+ return null;
+ }
+ }
+
+ public static List<SqlResultSetMapping> buildSqlResultsetMappings(Element element,
XMLContext.Default defaults) {
+ if ( element == null ) return new ArrayList<SqlResultSetMapping>();
+ List resultsetElementList = element.elements( "sql-result-set-mapping" );
+ List<SqlResultSetMapping> resultsets = new
ArrayList<SqlResultSetMapping>();
+ Iterator it = resultsetElementList.listIterator();
+ while ( it.hasNext() ) {
+ Element subelement = (Element) it.next();
+ AnnotationDescriptor ann = new AnnotationDescriptor( SqlResultSetMapping.class );
+ copyStringAttribute( ann, subelement, "name", true );
+ List<Element> elements = subelement.elements( "entity-result" );
+ List<EntityResult> entityResults = new ArrayList<EntityResult>(
elements.size() );
+ for (Element entityResult : elements) {
+ AnnotationDescriptor entityResultDescriptor = new AnnotationDescriptor(
EntityResult.class );
+ String clazzName = entityResult.attributeValue( "entity-class" );
+ if ( clazzName == null ) {
+ throw new AnnotationException( "<entity-result> without entity-class.
" + SCHEMA_VALIDATION );
+ }
+ Class clazz;
+ try {
+ clazz = ReflectHelper.classForName(
+ XMLContext.buildSafeClassName( clazzName, defaults ),
+ JPAOverridenAnnotationReader.class
+ );
+ }
+ catch (ClassNotFoundException e) {
+ throw new AnnotationException( "Unable to find entity-class: " +
clazzName, e );
+ }
+ entityResultDescriptor.setValue( "entityClass", clazz );
+ copyStringAttribute( entityResultDescriptor, entityResult,
"discriminator-column", false );
+ List<FieldResult> fieldResults = new ArrayList<FieldResult>();
+ for (Element fieldResult : (List<Element>) entityResult.elements(
"field-result" )) {
+ AnnotationDescriptor fieldResultDescriptor = new AnnotationDescriptor(
FieldResult.class );
+ copyStringAttribute( fieldResultDescriptor, fieldResult, "name", true );
+ copyStringAttribute( fieldResultDescriptor, fieldResult, "column", true
);
+ fieldResults.add( (FieldResult) AnnotationFactory.create( fieldResultDescriptor )
);
+ }
+ entityResultDescriptor.setValue(
+ "fields", fieldResults.toArray( new FieldResult[fieldResults.size()] )
+ );
+ entityResults.add( (EntityResult) AnnotationFactory.create( entityResultDescriptor )
);
+ }
+ ann.setValue( "entities", entityResults.toArray( new
EntityResult[entityResults.size()] ) );
+
+ elements = subelement.elements( "column-result" );
+ List<ColumnResult> columnResults = new ArrayList<ColumnResult>(
elements.size() );
+ for (Element columnResult : elements) {
+ AnnotationDescriptor columnResultDescriptor = new AnnotationDescriptor(
ColumnResult.class );
+ copyStringAttribute( columnResultDescriptor, columnResult, "name", true );
+ columnResults.add( (ColumnResult) AnnotationFactory.create( columnResultDescriptor )
);
+ }
+ ann.setValue( "columns", columnResults.toArray( new
ColumnResult[columnResults.size()] ) );
+ //FIXME there is never such a result-class, get rid of it?
+ String clazzName = subelement.attributeValue( "result-class" );
+ if ( StringHelper.isNotEmpty( clazzName ) ) {
+ Class clazz;
+ try {
+ clazz = ReflectHelper.classForName(
+ XMLContext.buildSafeClassName( clazzName, defaults ),
+ JPAOverridenAnnotationReader.class
+ );
+ }
+ catch (ClassNotFoundException e) {
+ throw new AnnotationException( "Unable to find entity-class: " +
clazzName, e );
+ }
+ ann.setValue( "resultClass", clazz );
+ }
+ copyStringAttribute( ann, subelement, "result-set-mapping", false );
+ resultsets.add( (SqlResultSetMapping) AnnotationFactory.create( ann ) );
+ }
+ return resultsets;
+ }
+
+ private void addSqlResultsetMappingIfNeeded(SqlResultSetMapping annotation,
List<SqlResultSetMapping> resultsets) {
+ if ( annotation != null ) {
+ String resultsetName = annotation.name();
+ boolean present = false;
+ for (SqlResultSetMapping current : resultsets) {
+ if ( current.name().equals( resultsetName ) ) {
+ present = true;
+ break;
+ }
+ }
+ if ( !present ) resultsets.add( annotation );
+ }
+ }
+
+ private NamedQueries getNamedQueries(Element tree, XMLContext.Default defaults) {
+ //TODO avoid the Proxy Creation (@NamedQueries) when possible
+ List<NamedQuery> queries = (List<NamedQuery>) buildNamedQueries( tree,
false, defaults );
+ if ( defaults.canUseJavaAnnotations() ) {
+ NamedQuery annotation = getJavaAnnotation( NamedQuery.class );
+ addNamedQueryIfNeeded( annotation, queries );
+ NamedQueries annotations = getJavaAnnotation( NamedQueries.class );
+ if ( annotations != null ) {
+ for (NamedQuery current : annotations.value()) {
+ addNamedQueryIfNeeded( current, queries );
+ }
+ }
+ }
+ if ( queries.size() > 0 ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( NamedQueries.class );
+ ad.setValue( "value", queries.toArray( new NamedQuery[queries.size()] ) );
+ return AnnotationFactory.create( ad );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private void addNamedQueryIfNeeded(NamedQuery annotation, List<NamedQuery>
queries) {
+ if ( annotation != null ) {
+ String queryName = annotation.name();
+ boolean present = false;
+ for (NamedQuery current : queries) {
+ if ( current.name().equals( queryName ) ) {
+ present = true;
+ break;
+ }
+ }
+ if ( !present ) queries.add( annotation );
+ }
+ }
+
+ private NamedNativeQueries getNamedNativeQueries(Element tree, XMLContext.Default
defaults) {
+ List<NamedNativeQuery> queries = (List<NamedNativeQuery>)
buildNamedQueries( tree, true, defaults );
+ if ( defaults.canUseJavaAnnotations() ) {
+ NamedNativeQuery annotation = getJavaAnnotation( NamedNativeQuery.class );
+ addNamedNativeQueryIfNeeded( annotation, queries );
+ NamedNativeQueries annotations = getJavaAnnotation( NamedNativeQueries.class );
+ if ( annotations != null ) {
+ for (NamedNativeQuery current : annotations.value()) {
+ addNamedNativeQueryIfNeeded( current, queries );
+ }
+ }
+ }
+ if ( queries.size() > 0 ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( NamedNativeQueries.class );
+ ad.setValue( "value", queries.toArray( new NamedNativeQuery[queries.size()]
) );
+ return AnnotationFactory.create( ad );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private void addNamedNativeQueryIfNeeded(NamedNativeQuery annotation,
List<NamedNativeQuery> queries) {
+ if ( annotation != null ) {
+ String queryName = annotation.name();
+ boolean present = false;
+ for (NamedNativeQuery current : queries) {
+ if ( current.name().equals( queryName ) ) {
+ present = true;
+ break;
+ }
+ }
+ if ( !present ) queries.add( annotation );
+ }
+ }
+
+ public static List buildNamedQueries(Element element, boolean isNative,
XMLContext.Default defaults) {
+ if ( element == null ) return new ArrayList();
+ List namedQueryElementList = isNative ?
+ element.elements( "named-native-query" ) :
+ element.elements( "named-query" );
+ List namedQueries = new ArrayList();
+ Iterator it = namedQueryElementList.listIterator();
+ while ( it.hasNext() ) {
+ Element subelement = (Element) it.next();
+ AnnotationDescriptor ann = new AnnotationDescriptor(
+ isNative ? NamedNativeQuery.class : NamedQuery.class
+ );
+ copyStringAttribute( ann, subelement, "name", false );
+ Element queryElt = subelement.element( "query" );
+ if ( queryElt == null ) throw new AnnotationException( "No <query> element
found." + SCHEMA_VALIDATION );
+ ann.setValue( "query", queryElt.getTextTrim() );
+ List<Element> elements = subelement.elements( "hint" );
+ List<QueryHint> queryHints = new ArrayList<QueryHint>( elements.size() );
+ for (Element hint : elements) {
+ AnnotationDescriptor hintDescriptor = new AnnotationDescriptor( QueryHint.class );
+ String value = hint.attributeValue( "name" );
+ if ( value == null ) throw new AnnotationException( "<hint> without name.
" + SCHEMA_VALIDATION );
+ hintDescriptor.setValue( "name", value );
+ value = hint.attributeValue( "value" );
+ if ( value == null ) throw new AnnotationException( "<hint> without value.
" + SCHEMA_VALIDATION );
+ hintDescriptor.setValue( "value", value );
+ queryHints.add( (QueryHint) AnnotationFactory.create( hintDescriptor ) );
+ }
+ ann.setValue( "hints", queryHints.toArray( new QueryHint[queryHints.size()]
) );
+ String clazzName = subelement.attributeValue( "result-class" );
+ if ( StringHelper.isNotEmpty( clazzName ) ) {
+ Class clazz;
+ try {
+ clazz = ReflectHelper.classForName(
+ XMLContext.buildSafeClassName( clazzName, defaults ),
+ JPAOverridenAnnotationReader.class
+ );
+ }
+ catch (ClassNotFoundException e) {
+ throw new AnnotationException( "Unable to find entity-class: " +
clazzName, e );
+ }
+ ann.setValue( "resultClass", clazz );
+ }
+ copyStringAttribute( ann, subelement, "result-set-mapping", false );
+ namedQueries.add( AnnotationFactory.create( ann ) );
+ }
+ return namedQueries;
+ }
+
+ private TableGenerator getTableGenerator(Element tree, XMLContext.Default defaults) {
+ Element element = tree != null ? tree.element( annotationToXml.get(
TableGenerator.class ) ) : null;
+ if ( element != null ) {
+ return buildTableGeneratorAnnotation( element, defaults );
+ }
+ else if ( defaults.canUseJavaAnnotations() && isJavaAnnotationPresent(
TableGenerator.class ) ) {
+ TableGenerator tableAnn = getJavaAnnotation( TableGenerator.class );
+ if ( StringHelper.isNotEmpty( defaults.getSchema() )
+ || StringHelper.isNotEmpty( defaults.getCatalog() ) ) {
+ AnnotationDescriptor annotation = new AnnotationDescriptor( TableGenerator.class );
+ annotation.setValue( "name", tableAnn.name() );
+ annotation.setValue( "table", tableAnn.table() );
+ annotation.setValue( "catalog", tableAnn.table() );
+ if ( StringHelper.isEmpty( (String) annotation.valueOf( "catalog" ) )
+ && StringHelper.isNotEmpty( defaults.getCatalog() ) ) {
+ annotation.setValue( "catalog", defaults.getCatalog() );
+ }
+ annotation.setValue( "schema", tableAnn.table() );
+ if ( StringHelper.isEmpty( (String) annotation.valueOf( "schema" ) )
+ && StringHelper.isNotEmpty( defaults.getSchema() ) ) {
+ annotation.setValue( "catalog", defaults.getSchema() );
+ }
+ annotation.setValue( "pkColumnName", tableAnn.pkColumnName() );
+ annotation.setValue( "valueColumnName", tableAnn.valueColumnName() );
+ annotation.setValue( "pkColumnValue", tableAnn.pkColumnValue() );
+ annotation.setValue( "initialValue", tableAnn.initialValue() );
+ annotation.setValue( "allocationSize", tableAnn.allocationSize() );
+ annotation.setValue( "uniqueConstraints", tableAnn.uniqueConstraints() );
+ return AnnotationFactory.create( annotation );
+ }
+ else {
+ return tableAnn;
+ }
+ }
+ else {
+ return null;
+ }
+ }
+
+ public static TableGenerator buildTableGeneratorAnnotation(Element element,
XMLContext.Default defaults) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( TableGenerator.class );
+ copyStringAttribute( ad, element, "name", false );
+ copyStringAttribute( ad, element, "table", false );
+ copyStringAttribute( ad, element, "catalog", false );
+ copyStringAttribute( ad, element, "schema", false );
+ copyStringAttribute( ad, element, "pk-column-name", false );
+ copyStringAttribute( ad, element, "value-column-name", false );
+ copyStringAttribute( ad, element, "pk-column-value", false );
+ copyIntegerAttribute( ad, element, "initial-value" );
+ copyIntegerAttribute( ad, element, "allocation-size" );
+ buildUniqueConstraints( ad, element );
+ if ( StringHelper.isEmpty( (String) ad.valueOf( "schema" ) )
+ && StringHelper.isNotEmpty( defaults.getSchema() ) ) {
+ ad.setValue( "schema", defaults.getSchema() );
+ }
+ if ( StringHelper.isEmpty( (String) ad.valueOf( "catalog" ) )
+ && StringHelper.isNotEmpty( defaults.getCatalog() ) ) {
+ ad.setValue( "catalog", defaults.getCatalog() );
+ }
+ return AnnotationFactory.create( ad );
+ }
+
+ private SequenceGenerator getSequenceGenerator(Element tree, XMLContext.Default
defaults) {
+ Element element = tree != null ? tree.element( annotationToXml.get(
SequenceGenerator.class ) ) : null;
+ if ( element != null ) {
+ return buildSequenceGeneratorAnnotation( element );
+ }
+ else if ( defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( SequenceGenerator.class );
+ }
+ else {
+ return null;
+ }
+ }
+
+ public static SequenceGenerator buildSequenceGeneratorAnnotation(Element element) {
+ if ( element != null ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( SequenceGenerator.class );
+ copyStringAttribute( ad, element, "name", false );
+ copyStringAttribute( ad, element, "sequence-name", false );
+ copyIntegerAttribute( ad, element, "initial-value" );
+ copyIntegerAttribute( ad, element, "allocation-size" );
+ return AnnotationFactory.create( ad );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private DiscriminatorColumn getDiscriminatorColumn(Element tree, XMLContext.Default
defaults) {
+ Element element = tree != null ? tree.element( "discriminator-column" ) :
null;
+ if ( element != null ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( DiscriminatorColumn.class );
+ copyStringAttribute( ad, element, "name", false );
+ copyStringAttribute( ad, element, "column-definition", false );
+ String value = element.attributeValue( "discriminator-type" );
+ DiscriminatorType type = DiscriminatorType.STRING;
+ if ( value != null ) {
+ if ( "STRING".equals( value ) ) {
+ type = DiscriminatorType.STRING;
+ }
+ else if ( "CHAR".equals( value ) ) {
+ type = DiscriminatorType.CHAR;
+ }
+ else if ( "INTEGER".equals( value ) ) {
+ type = DiscriminatorType.INTEGER;
+ }
+ else {
+ throw new AnnotationException(
+ "Unknown DiscrimiatorType in XML: " + value + " (" +
SCHEMA_VALIDATION + ")"
+ );
+ }
+ }
+ ad.setValue( "discriminatorType", type );
+ copyIntegerAttribute( ad, element, "length" );
+ return AnnotationFactory.create( ad );
+ }
+ else if ( defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( DiscriminatorColumn.class );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private DiscriminatorValue getDiscriminatorValue(Element tree, XMLContext.Default
defaults) {
+ Element element = tree != null ? tree.element( "discriminator-value" ) :
null;
+ if ( element != null ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( DiscriminatorValue.class );
+ copyStringElement( element, ad, "value" );
+ return AnnotationFactory.create( ad );
+ }
+ else if ( defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( DiscriminatorValue.class );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private Inheritance getInheritance(Element tree, XMLContext.Default defaults) {
+ Element element = tree != null ? tree.element( "inheritance" ) : null;
+ if ( element != null ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( Inheritance.class );
+ Attribute attr = element.attribute( "strategy" );
+ InheritanceType strategy = InheritanceType.SINGLE_TABLE;
+ if ( attr != null ) {
+ String value = attr.getValue();
+ if ( "SINGLE_TABLE".equals( value ) ) {
+ strategy = InheritanceType.SINGLE_TABLE;
+ }
+ else if ( "JOINED".equals( value ) ) {
+ strategy = InheritanceType.JOINED;
+ }
+ else if ( "TABLE_PER_CLASS".equals( value ) ) {
+ strategy = InheritanceType.TABLE_PER_CLASS;
+ }
+ else {
+ throw new AnnotationException(
+ "Unknown InheritanceType in XML: " + value + " (" +
SCHEMA_VALIDATION + ")"
+ );
+ }
+ }
+ ad.setValue( "strategy", strategy );
+ return AnnotationFactory.create( ad );
+ }
+ else if ( defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( Inheritance.class );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private IdClass getIdClass(Element tree, XMLContext.Default defaults) {
+ Element element = tree == null ? null : tree.element( "id-class" );
+ if ( element != null ) {
+ Attribute attr = element.attribute( "class" );
+ if ( attr != null ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( IdClass.class );
+ Class clazz;
+ try {
+ clazz = ReflectHelper.classForName(
+ XMLContext.buildSafeClassName( attr.getValue(), defaults ),
+ this.getClass()
+ );
+ }
+ catch (ClassNotFoundException e) {
+ throw new AnnotationException( "Unable to find id-class: " +
attr.getValue(), e );
+ }
+ ad.setValue( "value", clazz );
+ return AnnotationFactory.create( ad );
+ }
+ else {
+ throw new AnnotationException( "id-class without class. " +
SCHEMA_VALIDATION );
+ }
+ }
+ else if ( defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( IdClass.class );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private PrimaryKeyJoinColumns getPrimaryKeyJoinColumns(Element element,
XMLContext.Default defaults) {
+ PrimaryKeyJoinColumn[] columns = buildPrimaryKeyJoinColumns( element );
+ if ( columns.length == 0 && defaults.canUseJavaAnnotations() ) {
+ PrimaryKeyJoinColumn annotation = getJavaAnnotation( PrimaryKeyJoinColumn.class );
+ if ( annotation != null ) {
+ columns = new PrimaryKeyJoinColumn[] { annotation };
+ }
+ else {
+ PrimaryKeyJoinColumns annotations = getJavaAnnotation( PrimaryKeyJoinColumns.class
);
+ columns = annotations != null ? annotations.value() : columns;
+ }
+ }
+ if ( columns.length > 0 ) {
+ AnnotationDescriptor ad = new AnnotationDescriptor( PrimaryKeyJoinColumns.class );
+ ad.setValue( "value", columns );
+ return AnnotationFactory.create( ad );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private Entity getEntity(Element tree, XMLContext.Default defaults) {
+ if ( tree == null ) {
+ return defaults.canUseJavaAnnotations() ? getJavaAnnotation( Entity.class ) : null;
+ }
+ else {
+ if ( "entity".equals( tree.getName() ) ) {
+ AnnotationDescriptor entity = new AnnotationDescriptor( Entity.class );
+ copyStringAttribute( entity, tree, "name", false );
+ if ( defaults.canUseJavaAnnotations()
+ && StringHelper.isEmpty( (String) entity.valueOf( "name" ) ) ) {
+ Entity javaAnn = getJavaAnnotation( Entity.class );
+ if ( javaAnn != null ) entity.setValue( "name", javaAnn.name() );
+ }
+ return AnnotationFactory.create( entity );
+ }
+ else {
+ return null; //this is not an entity
+ }
+ }
+ }
+
+ private MappedSuperclass getMappedSuperclass(Element tree, XMLContext.Default defaults)
{
+ if ( tree == null ) {
+ return defaults.canUseJavaAnnotations() ? getJavaAnnotation( MappedSuperclass.class )
: null;
+ }
+ else {
+ if ( "mapped-superclass".equals( tree.getName() ) ) {
+ AnnotationDescriptor entity = new AnnotationDescriptor( MappedSuperclass.class );
+ return AnnotationFactory.create( entity );
+ }
+ else {
+ return null; //this is not an entity
+ }
+ }
+ }
+
+ private Embeddable getEmbeddable(Element tree, XMLContext.Default defaults) {
+ if ( tree == null ) {
+ return defaults.canUseJavaAnnotations() ? getJavaAnnotation( Embeddable.class ) :
null;
+ }
+ else {
+ if ( "embeddable".equals( tree.getName() ) ) {
+ AnnotationDescriptor entity = new AnnotationDescriptor( Embeddable.class );
+ return AnnotationFactory.create( entity );
+ }
+ else {
+ return null; //this is not an entity
+ }
+ }
+ }
+
+ private Table getTable(Element tree, XMLContext.Default defaults) {
+ Element subelement = tree == null ? null : tree.element( "table" );
+ if ( subelement == null ) {
+ //no element but might have some default or some annotation
+ if ( StringHelper.isNotEmpty( defaults.getCatalog() )
+ || StringHelper.isNotEmpty( defaults.getSchema() ) ) {
+ AnnotationDescriptor annotation = new AnnotationDescriptor( Table.class );
+ if ( defaults.canUseJavaAnnotations() ) {
+ Table table = getJavaAnnotation( Table.class );
+ if ( table != null ) {
+ annotation.setValue( "name", table.name() );
+ annotation.setValue( "schema", table.schema() );
+ annotation.setValue( "catalog", table.catalog() );
+ annotation.setValue( "uniqueConstraints", table.uniqueConstraints() );
+ }
+ }
+ if ( StringHelper.isEmpty( (String) annotation.valueOf( "schema" ) )
+ && StringHelper.isNotEmpty( defaults.getSchema() ) ) {
+ annotation.setValue( "schema", defaults.getSchema() );
+ }
+ if ( StringHelper.isEmpty( (String) annotation.valueOf( "catalog" ) )
+ && StringHelper.isNotEmpty( defaults.getCatalog() ) ) {
+ annotation.setValue( "catalog", defaults.getCatalog() );
+ }
+ return AnnotationFactory.create( annotation );
+ }
+ else if ( defaults.canUseJavaAnnotations() ) {
+ return getJavaAnnotation( Table.class );
+ }
+ else {
+ return null;
+ }
+ }
+ else {
+ //ignore java annotation, an element is defined
+ AnnotationDescriptor annotation = new AnnotationDescriptor( Table.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() );
+ }
+ buildUniqueConstraints( annotation, subelement );
+ return AnnotationFactory.create( annotation );
+ }
+ }
+
+ private SecondaryTables getSecondaryTables(Element tree, XMLContext.Default defaults) {
+ List<Element> elements = tree == null ?
+ new ArrayList<Element>() :
+ (List<Element>) tree.elements( "secondary-table" );
+ List<SecondaryTable> secondaryTables = new ArrayList<SecondaryTable>( 3 );
+ for (Element element : elements) {
+ AnnotationDescriptor annotation = new AnnotationDescriptor( SecondaryTable.class );
+ copyStringAttribute( annotation, element, "name", false );
+ copyStringAttribute( annotation, element, "catalog", false );
+ if ( StringHelper.isNotEmpty( defaults.getCatalog() )
+ && StringHelper.isEmpty( (String) annotation.valueOf( "catalog" )
) ) {
+ annotation.setValue( "catalog", defaults.getCatalog() );
+ }
+ copyStringAttribute( annotation, element, "schema", false );
+ if ( StringHelper.isNotEmpty( defaults.getSchema() )
+ && StringHelper.isEmpty( (String) annotation.valueOf( "schema" ) )
) {
+ annotation.setValue( "schema", defaults.getSchema() );
+ }
+ buildUniqueConstraints( annotation, element );
+ annotation.setValue( "pkJoinColumns", buildPrimaryKeyJoinColumns( element )
);
+ secondaryTables.add( (SecondaryTable) AnnotationFactory.create( annotation ) );
+ }
+ /*
+ * You can't have both secondary table in XML and Java,
+ * since there would be no way to "remove" a secondary table
+ */
+ if ( secondaryTables.size() == 0 && defaults.canUseJavaAnnotations() ) {
+ SecondaryTable secTableAnn = getJavaAnnotation( SecondaryTable.class );
+ overridesDefaultInSecondaryTable( secTableAnn, defaults, secondaryTables );
+ SecondaryTables secTablesAnn = getJavaAnnotation( SecondaryTables.class );
+ if ( secTablesAnn != null ) {
+ for (SecondaryTable table : secTablesAnn.value()) {
+ overridesDefaultInSecondaryTable( table, defaults, secondaryTables );
+ }
+ }
+ }
+ if ( secondaryTables.size() > 0 ) {
+ AnnotationDescriptor descriptor = new AnnotationDescriptor( SecondaryTables.class );
+ descriptor.setValue( "value", secondaryTables.toArray( new
SecondaryTable[secondaryTables.size()] ) );
+ return AnnotationFactory.create( descriptor );
+ }
+ else {
+ return null;
+ }
+ }
+
+ private void overridesDefaultInSecondaryTable(
+ SecondaryTable secTableAnn, XMLContext.Default defaults, List<SecondaryTable>
secondaryTables
+ ) {
+ if ( secTableAnn != null ) {
+ //handle default values
+ if ( StringHelper.isNotEmpty( defaults.getCatalog() )
+ || StringHelper.isNotEmpty( defaults.getSchema() ) ) {
+ AnnotationDescriptor annotation = new AnnotationDescriptor( SecondaryTable.class );
+ annotation.setValue( "name", secTableAnn.name() );
+ annotation.setValue( "schema", secTableAnn.schema() );
+ annotation.setValue( "catalog", secTableAnn.catalog() );
+ annotation.setValue( "uniqueConstraints", secTableAnn.uniqueConstraints()
);
+ annotation.setValue( "pkJoinColumns", secTableAnn.pkJoinColumns() );
+ if ( StringHelper.isEmpty( (String) annotation.valueOf( "schema" ) )
+ && StringHelper.isNotEmpty( defaults.getSchema() ) ) {
+ annotation.setValue( "schema", defaults.getSchema() );
+ }
+ if ( StringHelper.isEmpty( (String) annotation.valueOf( "catalog" ) )
+ && StringHelper.isNotEmpty( defaults.getCatalog() ) ) {
+ annotation.setValue( "catalog", defaults.getCatalog() );
+ }
+ secondaryTables.add( (SecondaryTable) AnnotationFactory.create( annotation ) );
+ }
+ else {
+ secondaryTables.add( secTableAnn );
+ }
+ }
+ }
+
+ private static void buildUniqueConstraints(AnnotationDescriptor annotation, Element
element) {
+ List uniqueConstraintElementList = element.elements( "unique-constraint" );
+ UniqueConstraint[] uniqueConstraints = new
UniqueConstraint[uniqueConstraintElementList.size()];
+ int ucIndex = 0;
+ Iterator ucIt = uniqueConstraintElementList.listIterator();
+ while ( ucIt.hasNext() ) {
+ Element subelement = (Element) ucIt.next();
+ List<Element> columnNamesElements = subelement.elements( "column-name"
);
+ String[] columnNames = new String[columnNamesElements.size()];
+ int columnNameIndex = 0;
+ Iterator it = columnNamesElements.listIterator();
+ while ( it.hasNext() ) {
+ Element columnNameElt = (Element) it.next();
+ columnNames[columnNameIndex++] = columnNameElt.getTextTrim();
+ }
+ AnnotationDescriptor ucAnn = new AnnotationDescriptor( UniqueConstraint.class );
+ ucAnn.setValue( "columnNames", columnNames );
+ uniqueConstraints[ucIndex++] = AnnotationFactory.create( ucAnn );
+ }
+ annotation.setValue( "uniqueConstraints", uniqueConstraints );
+ }
+
+ private PrimaryKeyJoinColumn[] buildPrimaryKeyJoinColumns(Element element) {
+ if ( element == null ) return new PrimaryKeyJoinColumn[] { };
+ List pkJoinColumnElementList = element.elements( "primary-key-join-column"
);
+ PrimaryKeyJoinColumn[] pkJoinColumns = new
PrimaryKeyJoinColumn[pkJoinColumnElementList.size()];
+ int index = 0;
+ Iterator pkIt = pkJoinColumnElementList.listIterator();
+ while ( pkIt.hasNext() ) {
+ Element subelement = (Element) pkIt.next();
+ AnnotationDescriptor pkAnn = new AnnotationDescriptor( PrimaryKeyJoinColumn.class );
+ copyStringAttribute( pkAnn, subelement, "name", false );
+ copyStringAttribute( pkAnn, subelement, "referenced-column-name", false );
+ copyStringAttribute( pkAnn, subelement, "column-definition", false );
+ pkJoinColumns[index++] = AnnotationFactory.create( pkAnn );
+ }
+ return pkJoinColumns;
+ }
+
+ private static void copyStringAttribute(
+ AnnotationDescriptor annotation, Element element, String attributeName, boolean
mandatory
+ ) {
+ String attribute = element.attributeValue( attributeName );
+ if ( attribute != null ) {
+ String annotationAttributeName = getJavaAttributeNameFromXMLOne( attributeName );
+ annotation.setValue( annotationAttributeName, attribute );
+ }
+ else {
+ if ( mandatory ) {
+ throw new AnnotationException(
+ element.getName() + "." + attributeName + " is mandatory in XML
overring. " + SCHEMA_VALIDATION
+ );
+ }
+ }
+ }
+
+ private static void copyIntegerAttribute(AnnotationDescriptor annotation, Element
element, String attributeName) {
+ String attribute = element.attributeValue( attributeName );
+ if ( attribute != null ) {
+ String annotationAttributeName = getJavaAttributeNameFromXMLOne( attributeName );
+ annotation.setValue( annotationAttributeName, attribute );
+ try {
+ int length = Integer.parseInt( attribute );
+ annotation.setValue( annotationAttributeName, length );
+ }
+ catch (NumberFormatException e) {
+ throw new AnnotationException(
+ element.getPath() + attributeName + " not parseable: " + attribute +
" (" + SCHEMA_VALIDATION + ")"
+ );
+ }
+ }
+ }
+
+ private static String getJavaAttributeNameFromXMLOne(String attributeName) {
+ StringBuilder annotationAttributeName = new StringBuilder( attributeName );
+ int index = annotationAttributeName.indexOf( WORD_SEPARATOR );
+ while ( index != -1 ) {
+ annotationAttributeName.deleteCharAt( index );
+ annotationAttributeName.setCharAt(
+ index, Character.toUpperCase( annotationAttributeName.charAt( index ) )
+ );
+ index = annotationAttributeName.indexOf( WORD_SEPARATOR );
+ }
+ return annotationAttributeName.toString();
+ }
+
+ private static void copyStringElement(Element element, AnnotationDescriptor ad, String
annotationAttribute) {
+ String discr = element.getTextTrim();
+ ad.setValue( annotationAttribute, discr );
+ }
+
+ private static void copyBooleanAttribute(AnnotationDescriptor descriptor, Element
element, String attribute) {
+ String attributeValue = element.attributeValue( attribute );
+ if ( StringHelper.isNotEmpty( attributeValue ) ) {
+ String javaAttribute = getJavaAttributeNameFromXMLOne( attribute );
+ descriptor.setValue( javaAttribute, Boolean.parseBoolean( attributeValue ) );
+ }
+ }
+
+ private <T extends Annotation> T getJavaAnnotation(Class<T> annotationType)
{
+ return element.getAnnotation( annotationType );
+ }
+
+ private <T extends Annotation> boolean isJavaAnnotationPresent(Class<T>
annotationType) {
+ return element.isAnnotationPresent( annotationType );
+ }
+
+ private Annotation[] getJavaAnnotations() {
+ return element.getAnnotations();
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/reflection/JPAOverridenAnnotationReader.java
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Copied:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/reflection/XMLContext.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/reflection/XMLContext.java)
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/reflection/XMLContext.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/reflection/XMLContext.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,313 @@
+// $Id$
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, 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.cfg.annotations.reflection;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.AccessType;
+
+import org.dom4j.Document;
+import org.dom4j.Element;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.util.StringHelper;
+
+import org.slf4j.LoggerFactory;
+import org.slf4j.Logger;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class XMLContext {
+ private Logger log = LoggerFactory.getLogger( XMLContext.class );
+ private Default globalDefaults;
+ private Map<String, Element> classOverriding = new HashMap<String,
Element>();
+ private Map<String, Default> defaultsOverriding = new HashMap<String,
Default>();
+ private List<Element> defaultElements = new ArrayList<Element>();
+ private List<String> defaultEntityListeners = new ArrayList<String>();
+ private boolean hasContext = false;
+
+ /**
+ * @param doc The xml document to add
+ * @return Add a xml document to this context and return the list of added class names.
+ */
+ @SuppressWarnings( "unchecked" )
+ public List<String> addDocument(Document doc) {
+ hasContext = true;
+ List<String> addedClasses = new ArrayList<String>();
+ Element root = doc.getRootElement();
+ //global defaults
+ Element metadata = root.element( "persistence-unit-metadata" );
+ if ( metadata != null ) {
+ if ( globalDefaults == null ) {
+ globalDefaults = new Default();
+ globalDefaults.setMetadataComplete(
+ metadata.element( "xml-mapping-metadata-complete" ) != null ?
+ Boolean.TRUE :
+ null
+ );
+ Element defaultElement = metadata.element( "persistence-unit-defaults" );
+ if ( defaultElement != null ) {
+ Element unitElement = defaultElement.element( "schema" );
+ globalDefaults.setSchema( unitElement != null ? unitElement.getTextTrim() : null );
+ unitElement = defaultElement.element( "catalog" );
+ globalDefaults.setCatalog( unitElement != null ? unitElement.getTextTrim() : null
);
+ unitElement = defaultElement.element( "access" );
+ setAccess( unitElement, globalDefaults );
+ unitElement = defaultElement.element( "cascade-persist" );
+ globalDefaults.setCascadePersist( unitElement != null ? Boolean.TRUE : null );
+ unitElement = defaultElement.element( "delimited-identifiers" );
+ globalDefaults.setDelimitedIdentifiers( unitElement != null ? Boolean.TRUE : null
);
+ defaultEntityListeners.addAll( addEntityListenerClasses( defaultElement, null,
addedClasses ) );
+ }
+ }
+ else {
+ log.warn( "Found more than one <persistence-unit-metadata>, subsequent
ignored" );
+ }
+ }
+
+ //entity mapping default
+ Default entityMappingDefault = new Default();
+ Element unitElement = root.element( "package" );
+ String packageName = unitElement != null ? unitElement.getTextTrim() : null;
+ entityMappingDefault.setPackageName( packageName );
+ unitElement = root.element( "schema" );
+ entityMappingDefault.setSchema( unitElement != null ? unitElement.getTextTrim() : null
);
+ unitElement = root.element( "catalog" );
+ entityMappingDefault.setCatalog( unitElement != null ? unitElement.getTextTrim() : null
);
+ unitElement = root.element( "access" );
+ setAccess( unitElement, entityMappingDefault );
+ defaultElements.add( root );
+
+ List<Element> entities = (List<Element>) root.elements( "entity"
);
+ addClass( entities, packageName, entityMappingDefault, addedClasses );
+
+ entities = (List<Element>) root.elements( "mapped-superclass" );
+ addClass( entities, packageName, entityMappingDefault, addedClasses );
+
+ entities = (List<Element>) root.elements( "embeddable" );
+ addClass( entities, packageName, entityMappingDefault, addedClasses );
+ return addedClasses;
+ }
+
+ private void setAccess(Element unitElement, Default defaultType) {
+ if ( unitElement != null ) {
+ String access = unitElement.getTextTrim();
+ setAccess( access, defaultType );
+ }
+ }
+
+ private void setAccess( String access, Default defaultType) {
+ AccessType type;
+ if ( access != null ) {
+ try {
+ type = AccessType.valueOf( access );
+ }
+ catch ( IllegalArgumentException e ) {
+ throw new AnnotationException( "Invalid access type " + access + "
(check your xml configuration)" );
+ }
+ defaultType.setAccess( type );
+ }
+ }
+
+ private void addClass(List<Element> entities, String packageName, Default
defaults, List<String> addedClasses) {
+ for (Element element : entities) {
+ String className = buildSafeClassName( element.attributeValue( "class" ),
packageName );
+ if ( classOverriding.containsKey( className ) ) {
+ //maybe switch it to warn?
+ throw new IllegalStateException( "Duplicate XML entry for " + className );
+ }
+ addedClasses.add( className );
+ classOverriding.put( className, element );
+ Default localDefault = new Default();
+ localDefault.override( defaults );
+ String metadataCompleteString = element.attributeValue( "metadata-complete"
);
+ if ( metadataCompleteString != null ) {
+ localDefault.setMetadataComplete( Boolean.parseBoolean( metadataCompleteString ) );
+ }
+ String access = element.attributeValue( "access" );
+ setAccess( access, localDefault );
+ defaultsOverriding.put( className, localDefault );
+
+ log.debug( "Adding XML overriding information for {}", className );
+ addEntityListenerClasses( element, packageName, addedClasses );
+ }
+ }
+
+ private List<String> addEntityListenerClasses(Element element, String packageName,
List<String> addedClasses) {
+ List<String> localAddedClasses = new ArrayList<String>();
+ Element listeners = element.element( "entity-listeners" );
+ if ( listeners != null ) {
+ @SuppressWarnings( "unchecked" )
+ List<Element> elements = (List<Element>) listeners.elements(
"entity-listener" );
+ for (Element listener : elements) {
+ String listenerClassName = buildSafeClassName( listener.attributeValue(
"class" ), packageName );
+ if ( classOverriding.containsKey( listenerClassName ) ) {
+ //maybe switch it to warn?
+ if ( "entity-listener".equals( classOverriding.get( listenerClassName
).getName() ) ) {
+ log.info(
+ "entity-listener duplication, first event definition will be used:
{}",
+ listenerClassName
+ );
+ continue;
+ }
+ else {
+ throw new IllegalStateException( "Duplicate XML entry for " +
listenerClassName );
+ }
+ }
+ localAddedClasses.add( listenerClassName );
+ classOverriding.put( listenerClassName, listener );
+ }
+ }
+ log.debug( "Adding XML overriding information for listener: {}",
localAddedClasses );
+ addedClasses.addAll( localAddedClasses );
+ return localAddedClasses;
+ }
+
+ public static String buildSafeClassName(String className, String defaultPackageName) {
+ if ( className.indexOf( '.' ) < 0 && StringHelper.isNotEmpty(
defaultPackageName ) ) {
+ className = StringHelper.qualify( defaultPackageName, className );
+ }
+ return className;
+ }
+
+ public static String buildSafeClassName(String className, XMLContext.Default defaults)
{
+ return buildSafeClassName( className, defaults.getPackageName() );
+ }
+
+ public Default getDefault(String className) {
+ Default xmlDefault = new Default();
+ xmlDefault.override( globalDefaults );
+ if ( className != null ) {
+ Default entityMappingOverriding = defaultsOverriding.get( className );
+ xmlDefault.override( entityMappingOverriding );
+ }
+ return xmlDefault;
+ }
+
+ public Element getXMLTree(String className ) {
+ return classOverriding.get( className );
+ }
+
+ public List<Element> getAllDocuments() {
+ return defaultElements;
+ }
+
+ public boolean hasContext() {
+ return hasContext;
+ }
+
+ public static class Default {
+ private AccessType access;
+ private String packageName;
+ private String schema;
+ private String catalog;
+ private Boolean metadataComplete;
+ private Boolean cascadePersist;
+ private Boolean delimitedIdentifier;
+
+ public AccessType getAccess() {
+ return access;
+ }
+
+ protected void setAccess(AccessType access) {
+ this.access = access;
+ }
+
+ public String getCatalog() {
+ return catalog;
+ }
+
+ protected void setCatalog(String catalog) {
+ this.catalog = catalog;
+ }
+
+ public String getPackageName() {
+ return packageName;
+ }
+
+ protected void setPackageName(String packageName) {
+ this.packageName = packageName;
+ }
+
+ public String getSchema() {
+ return schema;
+ }
+
+ protected void setSchema(String schema) {
+ this.schema = schema;
+ }
+
+ public Boolean getMetadataComplete() {
+ return metadataComplete;
+ }
+
+ public boolean canUseJavaAnnotations() {
+ return metadataComplete == null || !metadataComplete;
+ }
+
+ protected void setMetadataComplete(Boolean metadataComplete) {
+ this.metadataComplete = metadataComplete;
+ }
+
+ public Boolean getCascadePersist() {
+ return cascadePersist;
+ }
+
+ void setCascadePersist(Boolean cascadePersist) {
+ this.cascadePersist = cascadePersist;
+ }
+
+ public void override(Default globalDefault) {
+ if ( globalDefault != null ) {
+ if ( globalDefault.getAccess() != null ) access = globalDefault.getAccess();
+ if ( globalDefault.getPackageName() != null ) packageName =
globalDefault.getPackageName();
+ if ( globalDefault.getSchema() != null ) schema = globalDefault.getSchema();
+ if ( globalDefault.getCatalog() != null ) catalog = globalDefault.getCatalog();
+ if ( globalDefault.getDelimitedIdentifier() != null ) delimitedIdentifier =
globalDefault.getDelimitedIdentifier();
+ if ( globalDefault.getMetadataComplete() != null ) {
+ metadataComplete = globalDefault.getMetadataComplete();
+ }
+ //TODO fix that in stone if cascade-persist is set already?
+ if ( globalDefault.getCascadePersist() != null ) cascadePersist =
globalDefault.getCascadePersist();
+ }
+ }
+
+ public void setDelimitedIdentifiers(Boolean delimitedIdentifier) {
+ this.delimitedIdentifier = delimitedIdentifier;
+ }
+
+ public Boolean getDelimitedIdentifier() {
+ return delimitedIdentifier;
+ }
+ }
+
+ public List<String> getDefaultEntityListeners() {
+ return defaultEntityListeners;
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/annotations/reflection/XMLContext.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied:
core/trunk/core/src/main/java/org/hibernate/cfg/beanvalidation/BeanValidationActivator.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/beanvalidation/BeanValidationActivator.java)
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/cfg/beanvalidation/BeanValidationActivator.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/beanvalidation/BeanValidationActivator.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,152 @@
+package org.hibernate.cfg.beanvalidation;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Environment;
+import org.hibernate.event.EventListeners;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * This class has no hard dependency on Bean Validation APIs
+ * It must use reflection every time BV is required.
+ * @author Emmanuel Bernard
+ */
+public class BeanValidationActivator {
+
+ private static final String BV_DISCOVERY_CLASS =
"javax.validation.Validation";
+ private static final String TYPE_SAFE_ACTIVATOR_CLASS =
"org.hibernate.cfg.beanvalidation.TypeSafeActivator";
+ private static final String TYPE_SAFE_DDL_METHOD = "applyDDL";
+ private static final String TYPE_SAFE_ACTIVATOR_METHOD =
"activateBeanValidation";
+ private static final String MODE_PROPERTY =
"javax.persistence.validation.mode";
+
+ public static void activateBeanValidation(EventListeners eventListeners, Properties
properties) {
+ Set<ValidationMode> modes = ValidationMode.getModes( properties.get(
MODE_PROPERTY ) );
+
+ try {
+ //load Validation
+ ReflectHelper.classForName( BV_DISCOVERY_CLASS, BeanValidationActivator.class );
+ }
+ catch ( ClassNotFoundException e ) {
+ if ( modes.contains( ValidationMode.CALLBACK ) ) {
+ throw new HibernateException( "Bean Validation not available in the class path
but required in " + MODE_PROPERTY );
+ }
+ else if (modes.contains( ValidationMode.AUTO ) ) {
+ //nothing to activate
+ return;
+ }
+ }
+
+ //de-activate not-null tracking at the core level when Bean Validation
+ // is present unless the user really asks for it
+ //Note that if BV is not present, the behavior is backward compatible
+ if ( properties.getProperty( Environment.CHECK_NULLABILITY ) == null ) {
+ properties.setProperty( Environment.CHECK_NULLABILITY, "false" );
+ }
+
+ if ( ! ( modes.contains( ValidationMode.CALLBACK ) || modes.contains(
ValidationMode.AUTO ) ) ) return;
+
+ try {
+ Class<?> activator = ReflectHelper.classForName( TYPE_SAFE_ACTIVATOR_CLASS,
BeanValidationActivator.class );
+ Method activateBeanValidation =
+ activator.getMethod( TYPE_SAFE_ACTIVATOR_METHOD, EventListeners.class,
Properties.class );
+ activateBeanValidation.invoke( null, eventListeners, properties );
+ }
+ catch ( NoSuchMethodException e ) {
+ throw new HibernateException( "Unable to get the default Bean Validation
factory", e);
+ }
+ catch ( IllegalAccessException e ) {
+ throw new HibernateException( "Unable to get the default Bean Validation
factory", e);
+ }
+ catch ( InvocationTargetException e ) {
+ throw new HibernateException( "Unable to get the default Bean Validation
factory", e);
+ }
+ catch ( ClassNotFoundException e ) {
+ throw new HibernateException( "Unable to get the default Bean Validation
factory", e);
+ }
+ }
+
+ public static void applyDDL(Collection<PersistentClass> persistentClasses,
Properties properties) {
+ Set<ValidationMode> modes = ValidationMode.getModes( properties.get(
MODE_PROPERTY ) );
+ if ( ! ( modes.contains( ValidationMode.DDL ) || modes.contains( ValidationMode.AUTO )
) ) return;
+ try {
+ //load Validation
+ ReflectHelper.classForName( BV_DISCOVERY_CLASS, BeanValidationActivator.class );
+ }
+ catch ( ClassNotFoundException e ) {
+ if ( modes.contains( ValidationMode.DDL ) ) {
+ throw new HibernateException( "Bean Validation not available in the class path
but required in " + MODE_PROPERTY );
+ }
+ else if (modes.contains( ValidationMode.AUTO ) ) {
+ //nothing to activate
+ return;
+ }
+ }
+ try {
+ Class<?> activator = ReflectHelper.classForName( TYPE_SAFE_ACTIVATOR_CLASS,
BeanValidationActivator.class );
+ Method applyDDL =
+ activator.getMethod( TYPE_SAFE_DDL_METHOD, Collection.class, Properties.class );
+ applyDDL.invoke( null, persistentClasses, properties );
+ }
+ catch ( NoSuchMethodException e ) {
+ throw new HibernateException( "Unable to get the default Bean Validation
factory", e);
+ }
+ catch ( IllegalAccessException e ) {
+ throw new HibernateException( "Unable to get the default Bean Validation
factory", e);
+ }
+ catch ( InvocationTargetException e ) {
+ throw new HibernateException( "Unable to get the default Bean Validation
factory", e);
+ }
+ catch ( ClassNotFoundException e ) {
+ throw new HibernateException( "Unable to get the default Bean Validation
factory", e);
+ }
+ }
+
+ private static enum ValidationMode {
+ AUTO,
+ CALLBACK,
+ NONE,
+ DDL;
+
+ public static Set<ValidationMode> getModes(Object modeProperty) {
+ Set<ValidationMode> modes = new HashSet<ValidationMode>(3);
+ if (modeProperty == null) {
+ modes.add(ValidationMode.AUTO);
+ }
+ else {
+ final String[] modesInString = modeProperty.toString().split( "," );
+ for ( String modeInString : modesInString ) {
+ modes.add( getMode(modeInString) );
+ }
+ }
+ if ( modes.size() > 1 && ( modes.contains( ValidationMode.AUTO ) ||
modes.contains( ValidationMode.NONE ) ) ) {
+ StringBuilder message = new StringBuilder( "Incompatible validation modes mixed:
" );
+ for (ValidationMode mode : modes) {
+ message.append( mode ).append( ", " );
+ }
+ throw new HibernateException( message.substring( 0, message.length() - 2 ) );
+ }
+ return modes;
+ }
+
+ private static ValidationMode getMode(String modeProperty) {
+ if (modeProperty == null || modeProperty.length() == 0) {
+ return AUTO;
+ }
+ else {
+ try {
+ return valueOf( modeProperty.trim().toUpperCase() );
+ }
+ catch ( IllegalArgumentException e ) {
+ throw new HibernateException( "Unknown validation mode in " +
MODE_PROPERTY + ": " + modeProperty.toString() );
+ }
+ }
+ }
+ }
+}
Copied:
core/trunk/core/src/main/java/org/hibernate/cfg/beanvalidation/BeanValidationEventListener.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/beanvalidation/BeanValidationEventListener.java)
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/cfg/beanvalidation/BeanValidationEventListener.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/beanvalidation/BeanValidationEventListener.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,147 @@
+package org.hibernate.cfg.beanvalidation;
+
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import javax.validation.TraversableResolver;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.EntityMode;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.event.Initializable;
+import org.hibernate.event.PreDeleteEvent;
+import org.hibernate.event.PreDeleteEventListener;
+import org.hibernate.event.PreInsertEvent;
+import org.hibernate.event.PreInsertEventListener;
+import org.hibernate.event.PreUpdateEvent;
+import org.hibernate.event.PreUpdateEventListener;
+import org.hibernate.persister.entity.EntityPersister;
+
+/**
+ * Event listener used to enable Bean Validation for insert/update/delete events.
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+//FIXME review exception model
+public class BeanValidationEventListener implements
+ PreInsertEventListener, PreUpdateEventListener, PreDeleteEventListener, Initializable
{
+
+ private static final Logger log = LoggerFactory.getLogger(
BeanValidationEventListener.class );
+ private ValidatorFactory factory;
+ private ConcurrentHashMap<EntityPersister, Set<String>>
associationsPerEntityPersister =
+ new ConcurrentHashMap<EntityPersister, Set<String>>();
+ private GroupsPerOperation groupsPerOperation;
+ boolean initialized;
+
+ /**
+ * No-arg constructor used when listener is configured via configuration file
+ */
+ public BeanValidationEventListener() {
+ }
+
+ /**
+ * Constructor used in an environment where validator factory is injected (JPA2).
+ *
+ * @param factory The {@code ValidatorFactory} to use to create {@code Validator}
instance(s)
+ * @param properties Configued properties
+ */
+ public BeanValidationEventListener(ValidatorFactory factory, Properties properties) {
+ init( factory, properties );
+ }
+
+ public void initialize(Configuration cfg) {
+ if ( !initialized ) {
+ ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
+ Properties props = cfg.getProperties();
+ init( factory, props );
+ }
+ }
+
+ public boolean onPreInsert(PreInsertEvent event) {
+ validate(
+ event.getEntity(), event.getSession().getEntityMode(), event.getPersister(),
+ event.getSession().getFactory(), GroupsPerOperation.Operation.INSERT
+ );
+ return false;
+ }
+
+ public boolean onPreUpdate(PreUpdateEvent event) {
+ validate(
+ event.getEntity(), event.getSession().getEntityMode(), event.getPersister(),
+ event.getSession().getFactory(), GroupsPerOperation.Operation.UPDATE
+ );
+ return false;
+ }
+
+ public boolean onPreDelete(PreDeleteEvent event) {
+ validate(
+ event.getEntity(), event.getSession().getEntityMode(), event.getPersister(),
+ event.getSession().getFactory(), GroupsPerOperation.Operation.DELETE
+ );
+ return false;
+ }
+
+ private void init(ValidatorFactory factory, Properties properties) {
+ this.factory = factory;
+ groupsPerOperation = new GroupsPerOperation( properties );
+ initialized = true;
+ }
+
+ private <T> void validate(T object, EntityMode mode, EntityPersister persister,
+ SessionFactoryImplementor sessionFactory, GroupsPerOperation.Operation
operation) {
+ if ( object == null || mode != EntityMode.POJO ) {
+ return;
+ }
+ TraversableResolver tr = new HibernateTraversableResolver(
+ persister, associationsPerEntityPersister, sessionFactory
+ );
+ Validator validator = factory.usingContext()
+ .traversableResolver( tr )
+ .getValidator();
+ final Class<?>[] groups = groupsPerOperation.get( operation );
+ if ( groups.length > 0 ) {
+ final Set<ConstraintViolation<T>> constraintViolations =
validator.validate( object, groups );
+ if ( constraintViolations.size() > 0 ) {
+ Set<ConstraintViolation<?>> propagatedViolations =
+ new HashSet<ConstraintViolation<?>>( constraintViolations.size() );
+ Set<String> classNames = new HashSet<String>();
+ for ( ConstraintViolation<?> violation : constraintViolations ) {
+ if ( log.isTraceEnabled() ) {
+ log.trace( violation.toString() );
+ }
+ propagatedViolations.add( violation );
+ classNames.add( violation.getLeafBean().getClass().getName() );
+ }
+ StringBuilder builder = new StringBuilder();
+ builder.append( "validation failed for classes " );
+ builder.append( classNames );
+ builder.append( " during " );
+ builder.append( operation.getName() );
+ builder.append( " time for groups " );
+ builder.append( toString( groups ) );
+ throw new ConstraintViolationException(
+ builder.toString(), propagatedViolations
+ );
+ }
+ }
+ }
+
+ private String toString(Class<?>[] groups) {
+ StringBuilder toString = new StringBuilder( "[" );
+ for ( Class<?> group : groups ) {
+ toString.append( group.getName() ).append( ", " );
+ }
+ toString.append( "]" );
+ return toString.toString();
+ }
+}
Copied:
core/trunk/core/src/main/java/org/hibernate/cfg/beanvalidation/GroupsPerOperation.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/beanvalidation/GroupsPerOperation.java)
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/cfg/beanvalidation/GroupsPerOperation.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/beanvalidation/GroupsPerOperation.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,101 @@
+package org.hibernate.cfg.beanvalidation;
+
+import java.util.Properties;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import javax.validation.groups.Default;
+
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.HibernateException;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class GroupsPerOperation {
+
+ private static final String JPA_GROUP_PREFIX =
"javax.persistence.validation.group.";
+ private static final String HIBERNATE_GROUP_PREFIX =
"org.hibernate.validator.group.";
+ private static final Class<?>[] DEFAULT_GROUPS = new Class<?>[] {
Default.class };
+ private static final Class<?>[] EMPTY_GROUPS = new Class<?>[] { };
+
+ private Map<Operation, Class<?>[]> groupsPerOperation = new
HashMap<Operation, Class<?>[]>(4);
+
+ public GroupsPerOperation(Properties properties) {
+ setGroupsForOperation( Operation.INSERT, properties );
+ setGroupsForOperation( Operation.UPDATE, properties );
+ setGroupsForOperation( Operation.DELETE, properties );
+ setGroupsForOperation( Operation.DDL, properties );
+ }
+
+ private void setGroupsForOperation(Operation operation, Properties properties) {
+ Object property = properties.get( operation.getGroupPropertyName() );
+
+ Class<?>[] groups;
+ if ( property == null ) {
+ groups = operation == Operation.DELETE ? EMPTY_GROUPS : DEFAULT_GROUPS;
+ }
+ else {
+ if ( property instanceof String ) {
+ String stringProperty = (String) property;
+ String[] groupNames = stringProperty.split( "," );
+ if ( groupNames.length == 1 && groupNames[0].equals( "" ) ) {
+ groups = EMPTY_GROUPS;
+ }
+ else {
+ List<Class<?>> groupsList = new
ArrayList<Class<?>>(groupNames.length);
+ for (String groupName : groupNames) {
+ String cleanedGroupName = groupName.trim();
+ if ( cleanedGroupName.length() > 0) {
+ try {
+ groupsList.add( ReflectHelper.classForName( cleanedGroupName ) );
+ }
+ catch ( ClassNotFoundException e ) {
+ throw new HibernateException( "Unable to load class " +
cleanedGroupName, e );
+ }
+ }
+ }
+ groups = groupsList.toArray( new Class<?>[groupsList.size()] );
+ }
+ }
+ else if ( property instanceof Class<?>[] ) {
+ groups = (Class<?>[]) property;
+ }
+ else {
+ //null is bad and excluded by instanceof => exception is raised
+ throw new HibernateException( JPA_GROUP_PREFIX + operation.getGroupPropertyName() +
" is of unknown type: String or Class<?>[] only");
+ }
+ }
+ groupsPerOperation.put( operation, groups );
+ }
+
+ public Class<?>[] get(Operation operation) {
+ return groupsPerOperation.get( operation );
+ }
+
+ public static enum Operation {
+ INSERT("persist", JPA_GROUP_PREFIX + "pre-persist"),
+ UPDATE("update", JPA_GROUP_PREFIX + "pre-update"),
+ DELETE("remove", JPA_GROUP_PREFIX + "pre-remove"),
+ DDL("ddl", HIBERNATE_GROUP_PREFIX + "ddl");
+
+
+ private String exposedName;
+ private String groupPropertyName;
+
+ Operation(String exposedName, String groupProperty) {
+ this.exposedName = exposedName;
+ this.groupPropertyName = groupProperty;
+ }
+
+ public String getName() {
+ return exposedName;
+ }
+
+ public String getGroupPropertyName() {
+ return groupPropertyName;
+ }
+ }
+
+}
Copied:
core/trunk/core/src/main/java/org/hibernate/cfg/beanvalidation/HibernateTraversableResolver.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/beanvalidation/HibernateTraversableResolver.java)
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/cfg/beanvalidation/HibernateTraversableResolver.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/beanvalidation/HibernateTraversableResolver.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,126 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, 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.cfg.beanvalidation;
+
+import java.lang.annotation.ElementType;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.validation.TraversableResolver;
+import javax.validation.Path;
+
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.Hibernate;
+import org.hibernate.annotations.common.AssertionFailure;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.CompositeType;
+import org.hibernate.type.Type;
+import org.hibernate.type.CollectionType;
+
+/**
+ * Use Hibernate metadata to ignore cascade on entities.
+ * cascade on embeddable objects or collection of embeddable objects are accepted
+ *
+ * Also use Hibernate's native isInitialized method call.
+ *
+ * @author Emmanuel Bernard
+ */
+public class HibernateTraversableResolver implements TraversableResolver {
+ private Set<String> associations;
+
+ public HibernateTraversableResolver(
+ EntityPersister persister,
+ ConcurrentHashMap<EntityPersister, Set<String>>
associationsPerEntityPersister,
+ SessionFactoryImplementor factory) {
+ this.associations = associationsPerEntityPersister.get( persister );
+ if (this.associations == null) {
+ this.associations = new HashSet<String>();
+ addAssociationsToTheSetForAllProperties( persister.getPropertyNames(),
persister.getPropertyTypes(), "", factory );
+ associationsPerEntityPersister.put( persister, associations );
+ }
+ }
+
+ private void addAssociationsToTheSetForAllProperties(String[] names, Type[] types,
String prefix, SessionFactoryImplementor factory) {
+ final int length = names.length;
+ for( int index = 0 ; index < length; index++ ) {
+ addAssociationsToTheSetForOneProperty( names[index], types[index], prefix, factory );
+ }
+ }
+
+ private void addAssociationsToTheSetForOneProperty(String name, Type type, String
prefix, SessionFactoryImplementor factory) {
+
+ if ( type.isCollectionType() ) {
+ CollectionType collType = (CollectionType) type;
+ Type assocType = collType.getElementType( factory );
+ addAssociationsToTheSetForOneProperty(name, assocType, prefix, factory);
+ }
+ //ToOne association
+ else if ( type.isEntityType() || type.isAnyType() ) {
+ associations.add( prefix + name );
+ } else if ( type.isComponentType() ) {
+ CompositeType componentType = (CompositeType) type;
+ addAssociationsToTheSetForAllProperties(
+ componentType.getPropertyNames(),
+ componentType.getSubtypes(),
+ (prefix.equals( "" ) ? name : prefix + name) + ".",
+ factory);
+ }
+ }
+
+ private String getStringBasedPath(Path.Node traversableProperty, Path
pathToTraversableObject) {
+ StringBuilder path = new StringBuilder( );
+ for ( Path.Node node : pathToTraversableObject ) {
+ if (node.getName() != null) {
+ path.append( node.getName() ).append( "." );
+ }
+ }
+ if ( traversableProperty.getName() == null ) {
+ throw new AssertionFailure(
+ "TraversableResolver being passed a traversableProperty with null name.
pathToTraversableObject: "
+ + path.toString() );
+ }
+ path.append( traversableProperty.getName() );
+
+ return path.toString();
+ }
+
+ public boolean isReachable(Object traversableObject,
+ Path.Node traversableProperty,
+ Class<?> rootBeanType,
+ Path pathToTraversableObject,
+ ElementType elementType) {
+ //lazy, don't load
+ return Hibernate.isInitialized( traversableObject )
+ && Hibernate.isPropertyInitialized( traversableObject,
traversableProperty.getName() );
+ }
+
+ public boolean isCascadable(Object traversableObject,
+ Path.Node traversableProperty,
+ Class<?> rootBeanType,
+ Path pathToTraversableObject,
+ ElementType elementType) {
+ String path = getStringBasedPath( traversableProperty, pathToTraversableObject );
+ return ! associations.contains(path);
+ }
+}
Copied:
core/trunk/core/src/main/java/org/hibernate/cfg/beanvalidation/TypeSafeActivator.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/beanvalidation/TypeSafeActivator.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/beanvalidation/TypeSafeActivator.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/beanvalidation/TypeSafeActivator.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,328 @@
+package org.hibernate.cfg.beanvalidation;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.Collection;
+import javax.validation.metadata.BeanDescriptor;
+import javax.validation.metadata.ConstraintDescriptor;
+import javax.validation.metadata.PropertyDescriptor;
+import javax.validation.Validation;
+import javax.validation.ValidatorFactory;
+import javax.validation.constraints.Digits;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.event.EventListeners;
+import org.hibernate.event.PreDeleteEventListener;
+import org.hibernate.event.PreInsertEventListener;
+import org.hibernate.event.PreUpdateEventListener;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.SingleTableSubclass;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+class TypeSafeActivator {
+
+ private static final Logger logger = LoggerFactory.getLogger( TypeSafeActivator.class
);
+
+ private static final String FACTORY_PROPERTY =
"javax.persistence.validation.factory";
+
+ public static void activateBeanValidation(EventListeners eventListeners, Properties
properties) {
+ ValidatorFactory factory = getValidatorFactory( properties );
+ BeanValidationEventListener beanValidationEventListener = new
BeanValidationEventListener( factory, properties );
+
+ {
+ PreInsertEventListener[] listeners = eventListeners.getPreInsertEventListeners();
+ int length = listeners.length + 1;
+ PreInsertEventListener[] newListeners = new PreInsertEventListener[length];
+ System.arraycopy( listeners, 0, newListeners, 0, length - 1 );
+ newListeners[length - 1] = beanValidationEventListener;
+ eventListeners.setPreInsertEventListeners( newListeners );
+ }
+
+ {
+ PreUpdateEventListener[] listeners = eventListeners.getPreUpdateEventListeners();
+ int length = listeners.length + 1;
+ PreUpdateEventListener[] newListeners = new PreUpdateEventListener[length];
+ System.arraycopy( listeners, 0, newListeners, 0, length - 1 );
+ newListeners[length - 1] = beanValidationEventListener;
+ eventListeners.setPreUpdateEventListeners( newListeners );
+ }
+
+ {
+ PreDeleteEventListener[] listeners = eventListeners.getPreDeleteEventListeners();
+ int length = listeners.length + 1;
+ PreDeleteEventListener[] newListeners = new PreDeleteEventListener[length];
+ System.arraycopy( listeners, 0, newListeners, 0, length - 1 );
+ newListeners[length - 1] = beanValidationEventListener;
+ eventListeners.setPreDeleteEventListeners( newListeners );
+ }
+ }
+
+ public static void applyDDL(Collection<PersistentClass> persistentClasses,
Properties properties) {
+ ValidatorFactory factory = getValidatorFactory( properties );
+ Class<?>[] groupsArray = new GroupsPerOperation( properties ).get(
GroupsPerOperation.Operation.DDL );
+ Set<Class<?>> groups = new HashSet<Class<?>>( Arrays.asList(
groupsArray ) );
+
+ for ( PersistentClass persistentClass : persistentClasses ) {
+ final String className = persistentClass.getClassName();
+
+ if ( className == null || className.length() == 0) continue;
+ Class<?> clazz;
+ try {
+ clazz = ReflectHelper.classForName( className, TypeSafeActivator.class );
+ }
+ catch ( ClassNotFoundException e ) {
+ throw new AssertionFailure( "Entity class not found", e);
+ }
+
+ try {
+ applyDDL( "", persistentClass, clazz, factory, groups, true );
+ }
+ catch (Exception e) {
+ logger.warn( "Unable to apply constraints on DDL for " + className, e );
+ }
+ }
+ }
+
+ private static void applyDDL(String prefix,
+ PersistentClass persistentClass,
+ Class<?> clazz,
+ ValidatorFactory factory,
+ Set<Class<?>> groups,
+ boolean activateNotNull) {
+ final BeanDescriptor descriptor = factory.getValidator().getConstraintsForClass( clazz
);
+ //no bean level constraints can be applied, go to the properties
+
+ for ( PropertyDescriptor propertyDesc : descriptor.getConstrainedProperties() ) {
+ Property property = findPropertyByName( persistentClass, prefix +
propertyDesc.getPropertyName() );
+ boolean hasNotNull = false;
+ if ( property != null ) {
+ hasNotNull = applyConstraints( propertyDesc.getConstraintDescriptors(), property,
propertyDesc, groups, activateNotNull );
+ if ( property.isComposite() && propertyDesc.isCascaded() ) {
+ Class<?> componentClass = ( ( Component ) property.getValue()
).getComponentClass();
+
+ /*
+ * we can apply not null if the upper component let's us activate not null
+ * and if the property is not null.
+ * Otherwise, all sub columns should be left nullable
+ */
+ final boolean canSetNotNullOnColumns = activateNotNull && hasNotNull;
+ applyDDL( prefix + propertyDesc.getPropertyName() + ".",
+ persistentClass, componentClass, factory, groups,
+ canSetNotNullOnColumns
+ );
+ }
+ //FIXME add collection of components
+ }
+ }
+ }
+
+ private static boolean applyConstraints(Set<ConstraintDescriptor<?>>
constraintDescriptors,
+ Property property,
+ PropertyDescriptor propertyDesc,
+ Set<Class<?>> groups, boolean canApplyNotNull) {
+ boolean hasNotNull = false;
+ for (ConstraintDescriptor<?> descriptor : constraintDescriptors) {
+ if ( groups != null && Collections.disjoint( descriptor.getGroups(), groups) )
continue;
+
+ if ( canApplyNotNull ) {
+ hasNotNull = hasNotNull || applyNotNull( property, descriptor );
+ }
+
+ // apply bean validation specific constraints
+ applyDigits( property, descriptor );
+ applySize( property, descriptor, propertyDesc );
+ applyMin( property, descriptor );
+ applyMax( property, descriptor );
+
+ // apply hibernate validator specific constraints - we cannot import any HV specific
classes though!
+ applyLength( property, descriptor, propertyDesc );
+
+ // pass an empty set as composing constraints inherit the main constraint and thus are
matching already
+ hasNotNull = hasNotNull || applyConstraints(
+ descriptor.getComposingConstraints(),
+ property, propertyDesc, null,
+ canApplyNotNull );
+ }
+ return hasNotNull;
+ }
+
+ private static void applyMin(Property property, ConstraintDescriptor<?>
descriptor) {
+ if ( Min.class.equals( descriptor.getAnnotation().annotationType() ) ) {
+ @SuppressWarnings( "unchecked" )
+ ConstraintDescriptor<Min> minConstraint = (ConstraintDescriptor<Min>)
descriptor;
+ long min = minConstraint.getAnnotation().value();
+ Column col = (Column) property.getColumnIterator().next();
+ col.setCheckConstraint( col.getName() + ">=" + min );
+ }
+ }
+
+ private static void applyMax(Property property, ConstraintDescriptor<?>
descriptor) {
+ if ( Max.class.equals( descriptor.getAnnotation().annotationType() ) ) {
+ @SuppressWarnings( "unchecked" )
+ ConstraintDescriptor<Max> maxConstraint = (ConstraintDescriptor<Max>)
descriptor;
+ long max = maxConstraint.getAnnotation().value();
+ Column col = (Column) property.getColumnIterator().next();
+ col.setCheckConstraint( col.getName() + "<=" + max );
+ }
+ }
+
+ private static boolean applyNotNull(Property property, ConstraintDescriptor<?>
descriptor) {
+ boolean hasNotNull = false;
+ if ( NotNull.class.equals( descriptor.getAnnotation().annotationType() ) ) {
+ if ( ! ( property.getPersistentClass() instanceof SingleTableSubclass ) ) {
+ //single table should not be forced to null
+ if ( !property.isComposite() ) { //composite should not add not-null on all columns
+ @SuppressWarnings( "unchecked" )
+ Iterator<Column> iter = (Iterator<Column>)
property.getColumnIterator();
+ while ( iter.hasNext() ) {
+ iter.next().setNullable( false );
+ hasNotNull = true;
+ }
+ }
+ }
+ hasNotNull = true;
+ }
+ return hasNotNull;
+ }
+
+ private static void applyDigits(Property property, ConstraintDescriptor<?>
descriptor) {
+ if ( Digits.class.equals( descriptor.getAnnotation().annotationType() ) ) {
+ @SuppressWarnings( "unchecked" )
+ ConstraintDescriptor<Digits> digitsConstraint =
(ConstraintDescriptor<Digits>) descriptor;
+ int integerDigits = digitsConstraint.getAnnotation().integer();
+ int fractionalDigits = digitsConstraint.getAnnotation().fraction();
+ Column col = (Column) property.getColumnIterator().next();
+ col.setPrecision( integerDigits + fractionalDigits );
+ col.setScale( fractionalDigits );
+ }
+ }
+
+ private static void applySize(Property property, ConstraintDescriptor<?>
descriptor, PropertyDescriptor propertyDescriptor) {
+ if ( Size.class.equals( descriptor.getAnnotation().annotationType() )
+ && String.class.equals( propertyDescriptor.getElementClass() ) ) {
+ @SuppressWarnings("unchecked")
+ ConstraintDescriptor<Size> sizeConstraint = ( ConstraintDescriptor<Size> )
descriptor;
+ int max = sizeConstraint.getAnnotation().max();
+ Column col = ( Column ) property.getColumnIterator().next();
+ if ( max < Integer.MAX_VALUE ) {
+ col.setLength( max );
+ }
+ }
+ }
+
+ private static void applyLength(Property property, ConstraintDescriptor<?>
descriptor, PropertyDescriptor propertyDescriptor) {
+ if (
"org.hibernate.validator.constraints.Length".equals(descriptor.getAnnotation().annotationType().getName())
+ && String.class.equals( propertyDescriptor.getElementClass() ) ) {
+ @SuppressWarnings("unchecked")
+ int max = (Integer) descriptor.getAttributes().get( "max" );
+ Column col = ( Column ) property.getColumnIterator().next();
+ if ( max < Integer.MAX_VALUE ) {
+ col.setLength( max );
+ }
+ }
+ }
+
+ /**
+ * Retrieve the property by path in a recursive way, including IndentifierProperty in
the loop
+ * If propertyName is null or empty, the IdentifierProperty is returned
+ */
+ private static Property findPropertyByName(PersistentClass associatedClass, String
propertyName) {
+ Property property = null;
+ Property idProperty = associatedClass.getIdentifierProperty();
+ String idName = idProperty != null ? idProperty.getName() : null;
+ try {
+ if ( propertyName == null
+ || propertyName.length() == 0
+ || propertyName.equals( idName ) ) {
+ //default to id
+ property = idProperty;
+ }
+ else {
+ if ( propertyName.indexOf( idName + "." ) == 0 ) {
+ property = idProperty;
+ propertyName = propertyName.substring( idName.length() + 1 );
+ }
+ StringTokenizer st = new StringTokenizer( propertyName, ".", false );
+ while ( st.hasMoreElements() ) {
+ String element = (String) st.nextElement();
+ if ( property == null ) {
+ property = associatedClass.getProperty( element );
+ }
+ else {
+ if ( ! property.isComposite() ) return null;
+ property = ( ( Component ) property.getValue() ).getProperty( element );
+ }
+ }
+ }
+ }
+ catch ( MappingException e) {
+ try {
+ //if we do not find it try to check the identifier mapper
+ if ( associatedClass.getIdentifierMapper() == null ) return null;
+ StringTokenizer st = new StringTokenizer( propertyName, ".", false );
+ while ( st.hasMoreElements() ) {
+ String element = (String) st.nextElement();
+ if ( property == null ) {
+ property = associatedClass.getIdentifierMapper().getProperty( element );
+ }
+ else {
+ if ( ! property.isComposite() ) return null;
+ property = ( (Component) property.getValue() ).getProperty( element );
+ }
+ }
+ }
+ catch (MappingException ee) {
+ return null;
+ }
+ }
+ return property;
+ }
+
+ private static ValidatorFactory getValidatorFactory(Map<Object, Object>
properties) {
+ ValidatorFactory factory = null;
+ if ( properties != null ) {
+ Object unsafeProperty = properties.get( FACTORY_PROPERTY );
+ if (unsafeProperty != null) {
+ try {
+ factory = ValidatorFactory.class.cast( unsafeProperty );
+ }
+ catch ( ClassCastException e ) {
+ throw new HibernateException( "Property " + FACTORY_PROPERTY
+ + " should contain an object of type " +
ValidatorFactory.class.getName() );
+ }
+ }
+ }
+ if (factory == null) {
+ try {
+ factory = Validation.buildDefaultValidatorFactory();
+ }
+ catch ( Exception e ) {
+ throw new HibernateException( "Unable to build the default
ValidatorFactory", e);
+ }
+ }
+ return factory;
+ }
+
+}
Copied:
core/trunk/core/src/main/java/org/hibernate/cfg/search/HibernateSearchEventListenerRegister.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/cfg/search/HibernateSearchEventListenerRegister.java)
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/cfg/search/HibernateSearchEventListenerRegister.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/cfg/search/HibernateSearchEventListenerRegister.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,246 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.cfg.search;
+
+import java.util.Properties;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.event.EventListeners;
+import org.hibernate.event.PostCollectionRecreateEventListener;
+import org.hibernate.event.PostCollectionRemoveEventListener;
+import org.hibernate.event.PostCollectionUpdateEventListener;
+import org.hibernate.event.PostDeleteEventListener;
+import org.hibernate.event.PostInsertEventListener;
+import org.hibernate.event.PostUpdateEventListener;
+import org.hibernate.util.ReflectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Helper methods initializing Hibernate Search event listeners.
+ *
+ * @deprecated as of release 3.4.0.CR2, replaced by Hibernate Search's {@link
org.hibernate.search.cfg.EventListenerRegister}
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+@Deprecated
+public class HibernateSearchEventListenerRegister {
+
+ private static final Logger log =
LoggerFactory.getLogger(HibernateSearchEventListenerRegister.class);
+
+ /**
+ * Class name of the class needed to enable Search.
+ */
+ private static final String FULL_TEXT_INDEX_EVENT_LISTENER_CLASS =
"org.hibernate.search.event.FullTextIndexEventListener";
+
+ /**
+ * @deprecated as of release 3.4.0.CR2, replaced by Hibernate Search's {@link
org.hibernate.search.cfg.EventListenerRegister#enableHibernateSearch(EventListeners,
Properties)}
+ */
+ @SuppressWarnings("unchecked")
+ @Deprecated
+ public static void enableHibernateSearch(EventListeners eventListeners, Properties
properties) {
+ // check whether search is explicitly enabled - if so there is nothing
+ // to do
+ String enableSearchListeners = properties.getProperty(
"hibernate.search.autoregister_listeners" );
+ if("false".equalsIgnoreCase(enableSearchListeners )) {
+ log.info("Property hibernate.search.autoregister_listeners is set to false."
+
+ " No attempt will be made to register Hibernate Search event
listeners.");
+ return;
+ }
+
+ // add search events if the jar is available and class can be loaded
+ Class searchEventListenerClass = attemptToLoadSearchEventListener();
+ if ( searchEventListenerClass == null ) {
+ log.info("Unable to find {} on the classpath. Hibernate Search is not
enabled.", FULL_TEXT_INDEX_EVENT_LISTENER_CLASS);
+ return;
+ }
+
+ Object searchEventListener = instantiateEventListener(searchEventListenerClass);
+
+ //TODO Generalize this. Pretty much the same code all the time. Reflecetion?
+ {
+ boolean present = false;
+ PostInsertEventListener[] listeners = eventListeners
+ .getPostInsertEventListeners();
+ if (listeners != null) {
+ for (Object eventListener : listeners) {
+ // not isAssignableFrom since the user could subclass
+ present = present
+ || searchEventListenerClass == eventListener
+ .getClass();
+ }
+ if (!present) {
+ int length = listeners.length + 1;
+ PostInsertEventListener[] newListeners = new PostInsertEventListener[length];
+ System.arraycopy(listeners, 0, newListeners, 0, length - 1);
+ newListeners[length - 1] = (PostInsertEventListener) searchEventListener;
+ eventListeners.setPostInsertEventListeners(newListeners);
+ }
+ } else {
+ eventListeners
+ .setPostInsertEventListeners(new PostInsertEventListener[] {
(PostInsertEventListener) searchEventListener });
+ }
+ }
+ {
+ boolean present = false;
+ PostUpdateEventListener[] listeners = eventListeners
+ .getPostUpdateEventListeners();
+ if (listeners != null) {
+ for (Object eventListener : listeners) {
+ // not isAssignableFrom since the user could subclass
+ present = present
+ || searchEventListenerClass == eventListener
+ .getClass();
+ }
+ if (!present) {
+ int length = listeners.length + 1;
+ PostUpdateEventListener[] newListeners = new PostUpdateEventListener[length];
+ System.arraycopy(listeners, 0, newListeners, 0, length - 1);
+ newListeners[length - 1] = (PostUpdateEventListener) searchEventListener;
+ eventListeners.setPostUpdateEventListeners(newListeners);
+ }
+ } else {
+ eventListeners
+ .setPostUpdateEventListeners(new PostUpdateEventListener[] {
(PostUpdateEventListener) searchEventListener });
+ }
+ }
+ {
+ boolean present = false;
+ PostDeleteEventListener[] listeners = eventListeners
+ .getPostDeleteEventListeners();
+ if (listeners != null) {
+ for (Object eventListener : listeners) {
+ // not isAssignableFrom since the user could subclass
+ present = present
+ || searchEventListenerClass == eventListener
+ .getClass();
+ }
+ if (!present) {
+ int length = listeners.length + 1;
+ PostDeleteEventListener[] newListeners = new PostDeleteEventListener[length];
+ System.arraycopy(listeners, 0, newListeners, 0, length - 1);
+ newListeners[length - 1] = (PostDeleteEventListener) searchEventListener;
+ eventListeners.setPostDeleteEventListeners(newListeners);
+ }
+ } else {
+ eventListeners
+ .setPostDeleteEventListeners(new PostDeleteEventListener[] {
(PostDeleteEventListener) searchEventListener });
+ }
+ }
+ {
+ boolean present = false;
+ PostCollectionRecreateEventListener[] listeners =
eventListeners.getPostCollectionRecreateEventListeners();
+ if ( listeners != null ) {
+ for (Object eventListener : listeners) {
+ //not isAssignableFrom since the user could subclass
+ present = present || searchEventListenerClass == eventListener.getClass();
+ }
+ if ( !present ) {
+ int length = listeners.length + 1;
+ PostCollectionRecreateEventListener[] newListeners = new
PostCollectionRecreateEventListener[length];
+ System.arraycopy( listeners, 0, newListeners, 0, length - 1 );
+ newListeners[length - 1] = (PostCollectionRecreateEventListener)
searchEventListener;
+ eventListeners.setPostCollectionRecreateEventListeners( newListeners );
+ }
+ }
+ else {
+ eventListeners.setPostCollectionRecreateEventListeners(
+ new PostCollectionRecreateEventListener[] { (PostCollectionRecreateEventListener)
searchEventListener }
+ );
+ }
+ }
+ {
+ boolean present = false;
+ PostCollectionRemoveEventListener[] listeners =
eventListeners.getPostCollectionRemoveEventListeners();
+ if ( listeners != null ) {
+ for (Object eventListener : listeners) {
+ //not isAssignableFrom since the user could subclass
+ present = present || searchEventListenerClass == eventListener.getClass();
+ }
+ if ( !present ) {
+ int length = listeners.length + 1;
+ PostCollectionRemoveEventListener[] newListeners = new
PostCollectionRemoveEventListener[length];
+ System.arraycopy( listeners, 0, newListeners, 0, length - 1 );
+ newListeners[length - 1] = (PostCollectionRemoveEventListener) searchEventListener;
+ eventListeners.setPostCollectionRemoveEventListeners( newListeners );
+ }
+ }
+ else {
+ eventListeners.setPostCollectionRemoveEventListeners(
+ new PostCollectionRemoveEventListener[] { (PostCollectionRemoveEventListener)
searchEventListener }
+ );
+ }
+ }
+ {
+ boolean present = false;
+ PostCollectionUpdateEventListener[] listeners =
eventListeners.getPostCollectionUpdateEventListeners();
+ if ( listeners != null ) {
+ for (Object eventListener : listeners) {
+ //not isAssignableFrom since the user could subclass
+ present = present || searchEventListenerClass == eventListener.getClass();
+ }
+ if ( !present ) {
+ int length = listeners.length + 1;
+ PostCollectionUpdateEventListener[] newListeners = new
PostCollectionUpdateEventListener[length];
+ System.arraycopy( listeners, 0, newListeners, 0, length - 1 );
+ newListeners[length - 1] = (PostCollectionUpdateEventListener) searchEventListener;
+ eventListeners.setPostCollectionUpdateEventListeners( newListeners );
+ }
+ }
+ else {
+ eventListeners.setPostCollectionUpdateEventListeners(
+ new PostCollectionUpdateEventListener[] { (PostCollectionUpdateEventListener)
searchEventListener }
+ );
+ }
+ }
+ }
+
+ /**
+ * Tries to load Hibernate Search event listener.
+ *
+ * @return An event listener instance in case the jar was available.
+ */
+ private static Class<?> attemptToLoadSearchEventListener() {
+ Class searchEventListenerClass = null;
+ try {
+ searchEventListenerClass = ReflectHelper.classForName(
+ FULL_TEXT_INDEX_EVENT_LISTENER_CLASS,
+ HibernateSearchEventListenerRegister.class);
+ } catch (ClassNotFoundException e) {
+ log.debug("Search not present in classpath, ignoring event listener
registration.");
+ }
+ return searchEventListenerClass;
+ }
+
+ private static Object instantiateEventListener(Class<?> clazz) {
+ Object searchEventListener;
+ try {
+ searchEventListener = clazz.newInstance();
+ } catch (Exception e) {
+ throw new AnnotationException(
+ "Unable to load Search event listener", e);
+ }
+ return searchEventListener;
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/cfg/search/HibernateSearchEventListenerRegister.java
___________________________________________________________________
Name: svn:keywords
+ Id
Copied: core/trunk/core/src/main/java/org/hibernate/mapping/IdGenerator.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/mapping/IdGenerator.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/IdGenerator.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/mapping/IdGenerator.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,74 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.mapping;
+
+import java.io.Serializable;
+import java.util.Properties;
+
+/**
+ * Identifier generator container,
+ * Useful to keep named generator in annotations
+ *
+ * @author Emmanuel Bernard
+ */
+public class IdGenerator implements Serializable {
+ private String name;
+ private String identifierGeneratorStrategy;
+ private Properties params = new Properties();
+
+
+ /**
+ * @return identifier generator strategy
+ */
+ public String getIdentifierGeneratorStrategy() {
+ return identifierGeneratorStrategy;
+ }
+
+ /**
+ * @return generator name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @return generator configuration parameters
+ */
+ public Properties getParams() {
+ return params;
+ }
+
+ public void setIdentifierGeneratorStrategy(String string) {
+ identifierGeneratorStrategy = string;
+ }
+
+ public void setName(String string) {
+ name = string;
+ }
+
+ public void addParam(String key, String value) {
+ params.setProperty( key, value );
+ }
+
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/mapping/IdGenerator.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/mapping/SyntheticProperty.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/mapping/SyntheticProperty.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/SyntheticProperty.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/mapping/SyntheticProperty.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,37 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, 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.mapping;
+
+/**
+ * Models a property which does not actually exist in the model. It is created by
Hibernate during
+ * the metamodel binding process.
+ *
+ * @author Steve Ebersole
+ */
+public class SyntheticProperty extends Property {
+ @Override
+ public boolean isSynthetic() {
+ return true;
+ }
+}
Copied: core/trunk/core/src/main/java/org/hibernate/type/AbstractLobType.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/type/AbstractLobType.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/AbstractLobType.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/type/AbstractLobType.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,91 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.type;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * @author Emmanuel Bernard
+ * @deprecated
+ */
+@Deprecated
+public abstract class AbstractLobType extends AbstractType implements Serializable {
+ public boolean isDirty(Object old, Object current, boolean[] checkable,
SessionImplementor session)
+ throws HibernateException {
+ return checkable[0] ? ! isEqual( old, current, session.getEntityMode() ) : false;
+ }
+
+ @Override
+ public boolean isEqual(Object x, Object y, EntityMode entityMode) {
+ return isEqual( x, y, entityMode, null );
+ }
+
+ @Override
+ public int getHashCode(Object x, EntityMode entityMode) {
+ return getHashCode( x, entityMode, null );
+ }
+
+ public String getName() {
+ return this.getClass().getName();
+ }
+
+ public int getColumnSpan(Mapping mapping) throws MappingException {
+ return 1;
+ }
+
+ protected abstract Object get(ResultSet rs, String name) throws SQLException;
+
+ public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session,
Object owner)
+ throws HibernateException, SQLException {
+ return get( rs, names[0] );
+ }
+
+ public Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object
owner)
+ throws HibernateException, SQLException {
+ return get( rs, name );
+ }
+
+ public void nullSafeSet(
+ PreparedStatement st, Object value, int index, boolean[] settable, SessionImplementor
session
+ ) throws HibernateException, SQLException {
+ if ( settable[0] ) set( st, value, index, session );
+ }
+
+ protected abstract void set(PreparedStatement st, Object value, int index,
SessionImplementor session)
+ throws SQLException;
+
+ public void nullSafeSet(PreparedStatement st, Object value, int index,
SessionImplementor session)
+ throws HibernateException, SQLException {
+ set( st, value, index, session );
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/type/AbstractLobType.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/type/ByteArrayBlobType.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/type/ByteArrayBlobType.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/ByteArrayBlobType.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/type/ByteArrayBlobType.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,219 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, 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.type;
+
+import java.io.ByteArrayInputStream;
+import java.sql.Blob;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Map;
+
+import org.dom4j.Node;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.Hibernate;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * Map a Byte[] into a Blob
+ * Experimental
+ *
+ * @author Emmanuel Bernard
+ * @deprecated replaced by {@link org.hibernate.type.WrappedMaterializedBlobType}
+ */
+@Deprecated
+public class ByteArrayBlobType extends AbstractLobType {
+ private static final int[] TYPES = new int[] { Types.BLOB };
+
+ public int[] sqlTypes(Mapping mapping) {
+ return TYPES;
+ }
+
+ @Override
+ public boolean isEqual(Object x, Object y, EntityMode entityMode,
SessionFactoryImplementor factory) {
+ if ( x == y ) return true;
+ if ( x == null || y == null ) return false;
+ if ( x instanceof Byte[] ) {
+ Object[] o1 = (Object[]) x;
+ Object[] o2 = (Object[]) y;
+ return ArrayHelper.isEquals( o1, o2 );
+ }
+ else {
+ byte[] c1 = (byte[]) x;
+ byte[] c2 = (byte[]) y;
+ return ArrayHelper.isEquals( c1, c2 );
+ }
+ }
+
+ public int getHashCode(Object x, EntityMode entityMode, SessionFactoryImplementor
factory) {
+ if ( x instanceof Character[] ) {
+ Object[] o = (Object[]) x;
+ return ArrayHelper.hash( o );
+ }
+ else {
+ byte[] c = (byte[]) x;
+ return ArrayHelper.hash( c );
+ }
+ }
+
+ public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor
factory)
+ throws HibernateException {
+ if ( value == null ) return null;
+ if ( value instanceof Byte[] ) {
+ Byte[] array = (Byte[]) value;
+ int length = array.length;
+ Byte[] copy = new Byte[length];
+ for ( int index = 0; index < length ; index++ ) {
+ copy[index] = Byte.valueOf( array[index].byteValue() );
+ }
+ return copy;
+ }
+ else {
+ byte[] array = (byte[]) value;
+ int length = array.length;
+ byte[] copy = new byte[length];
+ System.arraycopy( array, 0, copy, 0, length );
+ return copy;
+ }
+ }
+
+ public Class getReturnedClass() {
+ return Byte[].class;
+ }
+
+ protected Object get(ResultSet rs, String name) throws SQLException {
+ Blob blob = rs.getBlob( name );
+ if ( rs.wasNull() ) return null;
+ int length = (int) blob.length();
+ byte[] primaryResult = blob.getBytes( 1, length );
+ return wrap( primaryResult );
+ }
+
+ protected void set(PreparedStatement st, Object value, int index, SessionImplementor
session) throws SQLException {
+ if ( value == null ) {
+ st.setNull( index, sqlTypes( null )[0] );
+ }
+ else {
+ byte[] toSet = unWrap( value );
+ final boolean useInputStream =
session.getFactory().getDialect().useInputStreamToInsertBlob();
+
+ if ( useInputStream ) {
+ st.setBinaryStream( index, new ByteArrayInputStream( toSet ), toSet.length );
+ }
+ else {
+ st.setBlob( index, Hibernate.getLobCreator( session ).createBlob( toSet ) );
+ }
+ }
+ }
+
+ public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory)
throws HibernateException {
+ node.setText( toString( value ) );
+ }
+
+ public String toString(Object val) {
+ byte[] bytes = unWrap( val );
+ StringBuilder buf = new StringBuilder( 2 * bytes.length );
+ for ( int i = 0; i < bytes.length ; i++ ) {
+ String hexStr = Integer.toHexString( bytes[i] - Byte.MIN_VALUE );
+ if ( hexStr.length() == 1 ) buf.append( '0' );
+ buf.append( hexStr );
+ }
+ return buf.toString();
+ }
+
+ public String toLoggableString(Object value, SessionFactoryImplementor factory) {
+ return value == null ? "null" : toString( value );
+ }
+
+ public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException {
+ String xmlText = xml.getText();
+ return xmlText == null || xmlText.length() == 0 ? null : fromString( xmlText );
+ }
+
+ private Object fromString(String xmlText) {
+ if ( xmlText == null ) {
+ return null;
+ }
+ if ( xmlText.length() % 2 != 0 ) {
+ throw new IllegalArgumentException( "The string is not a valid xml representation
of a binary content." );
+ }
+ byte[] bytes = new byte[xmlText.length() / 2];
+ for ( int i = 0; i < bytes.length ; i++ ) {
+ String hexStr = xmlText.substring( i * 2, ( i + 1 ) * 2 );
+ bytes[i] = (byte) ( Integer.parseInt( hexStr, 16 ) + Byte.MIN_VALUE );
+ }
+ return wrap( bytes );
+ }
+
+ protected Object wrap(byte[] bytes) {
+ return wrapPrimitive( bytes );
+ }
+
+ protected byte[] unWrap(Object bytes) {
+ return unwrapNonPrimitive( (Byte[]) bytes );
+ }
+
+ private byte[] unwrapNonPrimitive(Byte[] bytes) {
+ int length = bytes.length;
+ byte[] result = new byte[length];
+ for ( int i = 0; i < length ; i++ ) {
+ result[i] = bytes[i].byteValue();
+ }
+ return result;
+ }
+
+ private Byte[] wrapPrimitive(byte[] bytes) {
+ int length = bytes.length;
+ Byte[] result = new Byte[length];
+ for ( int index = 0; index < length ; index++ ) {
+ result[index] = Byte.valueOf( bytes[index] );
+ }
+ return result;
+ }
+
+ public boolean isMutable() {
+ return true;
+ }
+
+ public Object replace(
+ Object original,
+ Object target,
+ SessionImplementor session,
+ Object owner,
+ Map copyCache
+ )
+ throws HibernateException {
+ if ( isEqual( original, target, session.getEntityMode() ) ) return original;
+ return deepCopy( original, session.getEntityMode(), session.getFactory() );
+ }
+
+ public boolean[] toColumnNullness(Object value, Mapping mapping) {
+ return value == null ? ArrayHelper.FALSE : ArrayHelper.TRUE;
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/type/ByteArrayBlobType.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/type/CharacterArrayClobType.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/type/CharacterArrayClobType.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/CharacterArrayClobType.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/type/CharacterArrayClobType.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,49 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, 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.type;
+
+import org.hibernate.type.descriptor.java.CharacterArrayTypeDescriptor;
+import org.hibernate.type.descriptor.sql.ClobTypeDescriptor;
+
+/**
+ * A type that maps between {@link java.sql.Types#CLOB CLOB} and {@link Character
Character[]}
+ * <p/>
+ * Essentially a {@link MaterializedClobType} but represented as a Character[] in Java
rather than String.
+ *
+ * @author Emmanuel Bernard
+ * @author Steve Ebersole
+ */
+public class CharacterArrayClobType extends
AbstractSingleColumnStandardBasicType<Character[]> {
+ public static final CharacterArrayClobType INSTANCE = new CharacterArrayClobType();
+
+ public CharacterArrayClobType() {
+ super( ClobTypeDescriptor.INSTANCE, CharacterArrayTypeDescriptor.INSTANCE );
+ }
+
+ public String getName() {
+ // todo name these annotation types for addition to the registry
+ return null;
+ }
+
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/type/CharacterArrayClobType.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/type/EnumType.java (from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/type/EnumType.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/EnumType.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/type/EnumType.java 2010-07-08 23:41:23 UTC
(rev 19921)
@@ -0,0 +1,266 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.type;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.usertype.EnhancedUserType;
+import org.hibernate.usertype.ParameterizedType;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Enum type mapper
+ * Try and find the appropriate SQL type depending on column metadata
+ * <p/>
+ * TODO implements readobject/writeobject to recalculate the enumclasses
+ *
+ * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
+ */
+@SuppressWarnings("unchecked")
+public class EnumType implements EnhancedUserType, ParameterizedType, Serializable {
+ /**
+ * This is the old scheme where logging of parameter bindings and value extractions
+ * was controlled by the trace level enablement on the 'org.hibernate.type'
package...
+ * <p/>
+ * Originally was cached such because of performance of looking up the logger each time
+ * in order to check the trace-enablement. Driving this via a central Log-specific
class
+ * would alleviate that performance hit, and yet still allow more "normal"
logging usage/config.
+ */
+ private static final boolean IS_VALUE_TRACING_ENABLED = LoggerFactory.getLogger(
StringHelper.qualifier( Type.class.getName() ) )
+ .isTraceEnabled();
+ private transient Logger log;
+
+ private Logger log() {
+ if ( log == null ) {
+ log = LoggerFactory.getLogger( getClass() );
+ }
+ return log;
+ }
+
+ public static final String ENUM = "enumClass";
+ public static final String SCHEMA = "schema";
+ public static final String CATALOG = "catalog";
+ public static final String TABLE = "table";
+ public static final String COLUMN = "column";
+ public static final String TYPE = "type";
+
+ private Class<? extends Enum> enumClass;
+ private transient Object[] enumValues;
+ private int sqlType = Types.INTEGER; //before any guessing
+
+ public int[] sqlTypes() {
+ return new int[] { sqlType };
+ }
+
+ public Class<? extends Enum> returnedClass() {
+ return enumClass;
+ }
+
+ public boolean equals(Object x, Object y) throws HibernateException {
+ return x == y;
+ }
+
+ public int hashCode(Object x) throws HibernateException {
+ return x == null ? 0 : x.hashCode();
+ }
+
+
+ public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws
HibernateException, SQLException {
+ Object object = rs.getObject( names[0] );
+ if ( rs.wasNull() ) {
+ if ( IS_VALUE_TRACING_ENABLED ) {
+ log().debug( "Returning null as column {}", names[0] );
+ }
+ return null;
+ }
+ if ( object instanceof Number ) {
+ initEnumValues();
+ int ordinal = ( ( Number ) object ).intValue();
+ if ( ordinal < 0 || ordinal >= enumValues.length ) {
+ throw new IllegalArgumentException( "Unknown ordinal value for enum " +
enumClass + ": " + ordinal );
+ }
+ if ( IS_VALUE_TRACING_ENABLED ) {
+ log().debug( "Returning '{}' as column {}", ordinal, names[0] );
+ }
+ return enumValues[ordinal];
+ }
+ else {
+ String name = ( String ) object;
+ if ( IS_VALUE_TRACING_ENABLED ) {
+ log().debug( "Returning '{}' as column {}", name, names[0] );
+ }
+ try {
+ return Enum.valueOf( enumClass, name );
+ }
+ catch ( IllegalArgumentException iae ) {
+ throw new IllegalArgumentException( "Unknown name value for enum " +
enumClass + ": " + name, iae );
+ }
+ }
+ }
+
+ public void nullSafeSet(PreparedStatement st, Object value, int index) throws
HibernateException, SQLException {
+ if ( value == null ) {
+ if ( IS_VALUE_TRACING_ENABLED ) {
+ log().debug( "Binding null to parameter: {}", index );
+ }
+ st.setNull( index, sqlType );
+ }
+ else {
+ boolean isOrdinal = isOrdinal( sqlType );
+ if ( isOrdinal ) {
+ int ordinal = ( ( Enum<?> ) value ).ordinal();
+ if ( IS_VALUE_TRACING_ENABLED ) {
+ log().debug( "Binding '{}' to parameter: {}", ordinal, index );
+ }
+ st.setObject( index, Integer.valueOf( ordinal ), sqlType );
+ }
+ else {
+ String enumString = ( ( Enum<?> ) value ).name();
+ if ( IS_VALUE_TRACING_ENABLED ) {
+ log().debug( "Binding '{}' to parameter: {}", enumString, index
);
+ }
+ st.setObject( index, enumString, sqlType );
+ }
+ }
+ }
+
+ private boolean isOrdinal(int paramType) {
+ switch ( paramType ) {
+ case Types.INTEGER:
+ case Types.NUMERIC:
+ case Types.SMALLINT:
+ case Types.TINYINT:
+ case Types.BIGINT:
+ case Types.DECIMAL: //for Oracle Driver
+ case Types.DOUBLE: //for Oracle Driver
+ case Types.FLOAT: //for Oracle Driver
+ return true;
+ case Types.CHAR:
+ case Types.LONGVARCHAR:
+ case Types.VARCHAR:
+ return false;
+ default:
+ throw new HibernateException( "Unable to persist an Enum in a column of SQL
Type: " + paramType );
+ }
+ }
+
+ public Object deepCopy(Object value) throws HibernateException {
+ return value;
+ }
+
+ public boolean isMutable() {
+ return false;
+ }
+
+ public Serializable disassemble(Object value) throws HibernateException {
+ return ( Serializable ) value;
+ }
+
+ public Object assemble(Serializable cached, Object owner) throws HibernateException {
+ return cached;
+ }
+
+ public Object replace(Object original, Object target, Object owner) throws
HibernateException {
+ return original;
+ }
+
+ public void setParameterValues(Properties parameters) {
+ String enumClassName = parameters.getProperty( ENUM );
+ try {
+ enumClass = ReflectHelper.classForName( enumClassName, this.getClass() ).asSubclass(
Enum.class );
+ }
+ catch ( ClassNotFoundException exception ) {
+ throw new HibernateException( "Enum class not found", exception );
+ }
+
+ String type = parameters.getProperty( TYPE );
+ if ( type != null ) {
+ sqlType = Integer.decode( type );
+ }
+ }
+
+ /**
+ * Lazy init of {@link #enumValues}.
+ */
+ private void initEnumValues() {
+ if ( enumValues == null ) {
+ this.enumValues = enumClass.getEnumConstants();
+ if ( enumValues == null ) {
+ throw new NullPointerException( "Failed to init enumValues" );
+ }
+ }
+ }
+
+ public String objectToSQLString(Object value) {
+ boolean isOrdinal = isOrdinal( sqlType );
+ if ( isOrdinal ) {
+ int ordinal = ( ( Enum ) value ).ordinal();
+ return Integer.toString( ordinal );
+ }
+ else {
+ return '\'' + ( ( Enum ) value ).name() + '\'';
+ }
+ }
+
+ public String toXMLString(Object value) {
+ boolean isOrdinal = isOrdinal( sqlType );
+ if ( isOrdinal ) {
+ int ordinal = ( ( Enum ) value ).ordinal();
+ return Integer.toString( ordinal );
+ }
+ else {
+ return ( ( Enum ) value ).name();
+ }
+ }
+
+ public Object fromXMLString(String xmlValue) {
+ try {
+ int ordinal = Integer.parseInt( xmlValue );
+ initEnumValues();
+ if ( ordinal < 0 || ordinal >= enumValues.length ) {
+ throw new IllegalArgumentException( "Unknown ordinal value for enum " +
enumClass + ": " + ordinal );
+ }
+ return enumValues[ordinal];
+ }
+ catch ( NumberFormatException e ) {
+ try {
+ return Enum.valueOf( enumClass, xmlValue );
+ }
+ catch ( IllegalArgumentException iae ) {
+ throw new IllegalArgumentException( "Unknown name value for enum " +
enumClass + ": " + xmlValue, iae );
+ }
+ }
+ }
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/type/EnumType.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/type/PrimitiveByteArrayBlobType.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/type/PrimitiveByteArrayBlobType.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/PrimitiveByteArrayBlobType.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/type/PrimitiveByteArrayBlobType.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,45 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, 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.type;
+
+/**
+ * Map a byte[] to a Blob
+ *
+ * @author Emmanuel Bernard
+ * @deprecated replaced by {@link org.hibernate.type.MaterializedBlobType}
+ */
+@Deprecated
+public class PrimitiveByteArrayBlobType extends ByteArrayBlobType {
+ public Class getReturnedClass() {
+ return byte[].class;
+ }
+
+ protected Object wrap(byte[] bytes) {
+ return bytes;
+ }
+
+ protected byte[] unWrap(Object bytes) {
+ return (byte[]) bytes;
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/type/PrimitiveByteArrayBlobType.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied:
core/trunk/core/src/main/java/org/hibernate/type/PrimitiveCharacterArrayClobType.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/type/PrimitiveCharacterArrayClobType.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/PrimitiveCharacterArrayClobType.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/type/PrimitiveCharacterArrayClobType.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,45 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, 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.type;
+
+import org.hibernate.type.descriptor.java.PrimitiveCharacterArrayTypeDescriptor;
+import org.hibernate.type.descriptor.sql.ClobTypeDescriptor;
+
+/**
+ * Map a char[] to a Clob
+ *
+ * @author Emmanuel Bernard
+ */
+public class PrimitiveCharacterArrayClobType extends
AbstractSingleColumnStandardBasicType<char[]> {
+ public static final CharacterArrayClobType INSTANCE = new CharacterArrayClobType();
+
+ public PrimitiveCharacterArrayClobType() {
+ super( ClobTypeDescriptor.INSTANCE, PrimitiveCharacterArrayTypeDescriptor.INSTANCE );
+ }
+
+ public String getName() {
+ // todo name these annotation types for addition to the registry
+ return null;
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/type/PrimitiveCharacterArrayClobType.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/type/SerializableToBlobType.java (from
rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/type/SerializableToBlobType.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/SerializableToBlobType.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/type/SerializableToBlobType.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,157 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ *
+ * 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.type;
+
+import java.io.ByteArrayInputStream;
+import java.io.Serializable;
+import java.sql.Blob;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Map;
+import java.util.Properties;
+
+import org.dom4j.Node;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.Hibernate;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.usertype.ParameterizedType;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.SerializationHelper;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class SerializableToBlobType extends AbstractLobType implements ParameterizedType
{
+ /**
+ * class name of the serialisable class
+ */
+ public static final String CLASS_NAME = "classname";
+ private Class serializableClass;
+ private SerializableType type;
+
+ public int[] sqlTypes(Mapping mapping) throws MappingException {
+ return new int[]{Types.BLOB};
+ }
+
+ public Class getReturnedClass() {
+ return serializableClass;
+ }
+
+ @Override
+ public boolean isEqual(Object x, Object y, EntityMode entityMode,
SessionFactoryImplementor factory) {
+ return type.isEqual( x, y );
+ }
+
+
+ @Override
+ public int getHashCode(Object x, EntityMode entityMode, SessionFactoryImplementor
session) {
+ return type.getHashCode( x, null );
+ }
+
+ public Object get(ResultSet rs, String name) throws SQLException {
+ Blob blob = rs.getBlob( name );
+ if ( rs.wasNull() ) return null;
+ int length = (int) blob.length();
+ byte[] primaryResult = blob.getBytes( 1, length );
+ return fromBytes( primaryResult );
+ }
+
+ private static byte[] toBytes(Object object) throws SerializationException {
+ return SerializationHelper.serialize( (Serializable) object );
+ }
+
+ private Object fromBytes(byte[] bytes) throws SerializationException {
+ return SerializationHelper.deserialize( bytes, getReturnedClass().getClassLoader() );
+ }
+
+ public void set(PreparedStatement st, Object value, int index, SessionImplementor
session) throws SQLException {
+ if ( value != null ) {
+ byte[] toSet;
+ toSet = toBytes( value );
+ if ( session.getFactory().getDialect().useInputStreamToInsertBlob() ) {
+ st.setBinaryStream( index, new ByteArrayInputStream( toSet ), toSet.length );
+ }
+ else {
+ st.setBlob( index, Hibernate.getLobCreator( session ).createBlob( toSet ) );
+ }
+ }
+ else {
+ st.setNull( index, sqlTypes( null )[0] );
+ }
+ }
+
+ public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory)
throws HibernateException {
+ type.setToXMLNode( node, value, factory );
+ }
+
+ public String toLoggableString(Object value, SessionFactoryImplementor factory) throws
HibernateException {
+ return type.toLoggableString( value, factory );
+ }
+
+ public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException {
+ return type.fromXMLNode( xml, factory );
+ }
+
+ public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor
factory)
+ throws HibernateException {
+ return type.deepCopy( value, null, null );
+ }
+
+ public boolean isMutable() {
+ return type.isMutable();
+ }
+
+ public Object replace(Object original, Object target, SessionImplementor session, Object
owner, Map copyCache)
+ throws HibernateException {
+ return type.replace( original, target, session, owner, copyCache );
+ }
+
+ public boolean[] toColumnNullness(Object value, Mapping mapping) {
+ return type.toColumnNullness( value, mapping );
+ }
+
+ public void setParameterValues(Properties parameters) {
+ if ( parameters != null ) {
+ String className = parameters.getProperty( CLASS_NAME );
+ if ( className == null ) {
+ throw new MappingException(
+ "No class name defined for type: " +
SerializableToBlobType.class.getName()
+ );
+ }
+ try {
+ serializableClass = ReflectHelper.classForName( className );
+ }
+ catch (ClassNotFoundException e) {
+ throw new MappingException( "Unable to load class from " + CLASS_NAME +
" parameter", e );
+ }
+ }
+ type = new SerializableType( serializableClass );
+ }
+}
Property changes on:
core/trunk/core/src/main/java/org/hibernate/type/SerializableToBlobType.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/type/StringClobType.java (from rev
19909, core/trunk/annotations/src/main/java/org/hibernate/type/StringClobType.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/StringClobType.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/type/StringClobType.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,109 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, 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.type;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Serializable;
+import java.io.StringReader;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.hibernate.HibernateException;
+import org.hibernate.usertype.UserType;
+
+/**
+ * Map a String to a Clob
+ *
+ * @author Emmanuel Bernard
+ * @deprecated replaced by {@link org.hibernate.type.MaterializedClobType}
+ */
+@Deprecated
+public class StringClobType implements UserType, Serializable {
+ public int[] sqlTypes() {
+ return new int[]{Types.CLOB};
+ }
+
+ public Class returnedClass() {
+ return String.class;
+ }
+
+ public boolean equals(Object x, Object y) throws HibernateException {
+ return ( x == y ) || ( x != null && x.equals( y ) );
+ }
+
+ public int hashCode(Object x) throws HibernateException {
+ return x.hashCode();
+ }
+
+ public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws
HibernateException, SQLException {
+ Reader reader = rs.getCharacterStream( names[0] );
+ if ( reader == null ) return null;
+ StringBuilder result = new StringBuilder( 4096 );
+ try {
+ char[] charbuf = new char[4096];
+ for ( int i = reader.read( charbuf ); i > 0 ; i = reader.read( charbuf ) ) {
+ result.append( charbuf, 0, i );
+ }
+ }
+ catch (IOException e) {
+ throw new SQLException( e.getMessage() );
+ }
+ return result.toString();
+ }
+
+ public void nullSafeSet(PreparedStatement st, Object value, int index) throws
HibernateException, SQLException {
+ if ( value != null ) {
+ String string = (String) value;
+ StringReader reader = new StringReader( string );
+ st.setCharacterStream( index, reader, string.length() );
+ }
+ else {
+ st.setNull( index, sqlTypes()[0] );
+ }
+ }
+
+ public Object deepCopy(Object value) throws HibernateException {
+ //returning value should be OK since String are immutable
+ return value;
+ }
+
+ public boolean isMutable() {
+ return false;
+ }
+
+ public Serializable disassemble(Object value) throws HibernateException {
+ return (Serializable) value;
+ }
+
+ public Object assemble(Serializable cached, Object owner) throws HibernateException {
+ return cached;
+ }
+
+ public Object replace(Object original, Object target, Object owner) throws
HibernateException {
+ return original;
+ }
+}
Property changes on: core/trunk/core/src/main/java/org/hibernate/type/StringClobType.java
___________________________________________________________________
Name: svn:keywords
+ Date Revision Author Id
Name: svn:eol-style
+ native
Copied: core/trunk/core/src/main/java/org/hibernate/type/WrappedMaterializedBlobType.java
(from rev 19909,
core/trunk/annotations/src/main/java/org/hibernate/type/WrappedMaterializedBlobType.java)
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/WrappedMaterializedBlobType.java
(rev 0)
+++
core/trunk/core/src/main/java/org/hibernate/type/WrappedMaterializedBlobType.java 2010-07-08
23:41:23 UTC (rev 19921)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, 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.type;
+
+import org.hibernate.type.descriptor.java.ByteArrayTypeDescriptor;
+import org.hibernate.type.descriptor.sql.BlobTypeDescriptor;
+
+/**
+ * A type that maps JDBC {@link java.sql.Types#BLOB BLOB} and {@code Byte[]}.
+ * A type that maps an SQL BLOB to Java Byte[].
+ *
+ * @author Strong Liu
+ */
+public class WrappedMaterializedBlobType extends
AbstractSingleColumnStandardBasicType<Byte[]> {
+ public static final WrappedMaterializedBlobType INSTANCE = new
WrappedMaterializedBlobType();
+
+ public WrappedMaterializedBlobType() {
+ super( BlobTypeDescriptor.INSTANCE, ByteArrayTypeDescriptor.INSTANCE );
+ }
+
+ public String getName() {
+ // todo name these annotation types for addition to the registry
+ return null;
+ }
+}
Copied: core/trunk/core/src/main/resources/org/hibernate/ejb/orm_1_0.xsd (from rev 19909,
core/trunk/annotations/src/main/resources/org/hibernate/ejb/orm_1_0.xsd)
===================================================================
--- core/trunk/core/src/main/resources/org/hibernate/ejb/orm_1_0.xsd
(rev 0)
+++ core/trunk/core/src/main/resources/org/hibernate/ejb/orm_1_0.xsd 2010-07-08 23:41:23
UTC (rev 19921)
@@ -0,0 +1,1540 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Hibernate, Relational Persistence for Idiomatic Java
+ ~
+ ~ Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
+ ~
+ ~ 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
+ -->
+
+<!-- Java Persistence API object-relational mapping file schema -->
+<xsd:schema
targetNamespace="http://java.sun.com/xml/ns/persistence/orm"
+
xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
+
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ version="1.0">
+
+ <xsd:annotation>
+ <xsd:documentation>
+ @(#)orm_1_0.xsd 1.0 Feb 14 2006
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+
+ This is the XML Schema for the persistence object-relational
+ mapping file.
+ The file may be named "META-INF/orm.xml" in the persistence
+ archive or it may be named some other name which would be
+ used to locate the file as resource on the classpath.
+
+ ]]></xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:complexType name="emptyType"/>
+
+ <xsd:simpleType name="versionType">
+ <xsd:restriction base="xsd:token">
+ <xsd:pattern value="[0-9]+(\.[0-9]+)*"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <!-- **************************************************** -->
+
+ <xsd:element name="entity-mappings">
+ <xsd:complexType>
+ <xsd:annotation>
+ <xsd:documentation>
+
+ The entity-mappings element is the root element of an mapping
+ file. It contains the following four types of elements:
+
+ 1. The persistence-unit-metadata element contains metadata
+ for the entire persistence unit. It is undefined if this element
+ occurs in multiple mapping files within the same persistence unit.
+
+ 2. The package, schema, catalog and access elements apply to all of
+ the entity, mapped-superclass and embeddable elements defined in
+ the same file in which they occur.
+
+ 3. The sequence-generator, table-generator, named-query,
+ named-native-query and sql-result-set-mapping elements are global
+ to the persistence unit. It is undefined to have more than one
+ sequence-generator or table-generator of the same name in the same
+ or different mapping files in a persistence unit. It is also
+ undefined to have more than one named-query or named-native-query
+ of the same name in the same or different mapping files in a
+ persistence unit.
+
+ 4. The entity, mapped-superclass and embeddable elements each define
+ the mapping information for a managed persistent class. The mapping
+ information contained in these elements may be complete or it may
+ be partial.
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
+ minOccurs="0"/>
+ <xsd:element name="persistence-unit-metadata"
+ type="orm:persistence-unit-metadata"
+ minOccurs="0"/>
+ <xsd:element name="package" type="xsd:string"
+ minOccurs="0"/>
+ <xsd:element name="schema" type="xsd:string"
+ minOccurs="0"/>
+ <xsd:element name="catalog" type="xsd:string"
+ minOccurs="0"/>
+ <xsd:element name="access" type="orm:access-type"
+ minOccurs="0"/>
+ <xsd:element name="sequence-generator"
type="orm:sequence-generator"
+ minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="table-generator"
type="orm:table-generator"
+ minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="named-query"
type="orm:named-query"
+ minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="named-native-query"
type="orm:named-native-query"
+ minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="sql-result-set-mapping"
+ type="orm:sql-result-set-mapping"
+ minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="mapped-superclass"
type="orm:mapped-superclass"
+ minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="entity" type="orm:entity"
+ minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="embeddable"
type="orm:embeddable"
+ minOccurs="0"
maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="version" type="orm:versionType"
+ fixed="1.0" use="required"/>
+ </xsd:complexType>
+ </xsd:element>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="persistence-unit-metadata">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ Metadata that applies to the persistence unit and not just to
+ the mapping file in which it is contained.
+
+ If the xml-mapping-metadata-complete element is specified then
+ the complete set of mapping metadata for the persistence unit
+ is contained in the XML mapping files for the persistence unit.
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="xml-mapping-metadata-complete"
type="orm:emptyType"
+ minOccurs="0"/>
+ <xsd:element name="persistence-unit-defaults"
+ type="orm:persistence-unit-defaults"
+ minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="persistence-unit-defaults">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ These defaults are applied to the persistence unit as a whole
+ unless they are overridden by local annotation or XML
+ element settings.
+
+ schema - Used as the schema for all tables or secondary tables
+ that apply to the persistence unit
+ catalog - Used as the catalog for all tables or secondary tables
+ that apply to the persistence unit
+ access - Used as the access type for all managed classes in
+ the persistence unit
+ cascade-persist - Adds cascade-persist to the set of cascade options
+ in entity relationships of the persistence unit
+ entity-listeners - List of default entity listeners to be invoked
+ on each entity in the persistence unit.
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="schema" type="xsd:string"
+ minOccurs="0"/>
+ <xsd:element name="catalog" type="xsd:string"
+ minOccurs="0"/>
+ <xsd:element name="access" type="orm:access-type"
+ minOccurs="0"/>
+ <xsd:element name="cascade-persist"
type="orm:emptyType"
+ minOccurs="0"/>
+ <xsd:element name="entity-listeners"
type="orm:entity-listeners"
+ minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="entity">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ Defines the settings and mappings for an entity. Is allowed to be
+ sparsely populated and used in conjunction with the annotations.
+ Alternatively, the metadata-complete attribute can be used to
+ indicate that no annotations on the entity class (and its fields
+ or properties) are to be processed. If this is the case then
+ the defaulting rules for the entity and its subelements will
+ be recursively applied.
+
+ @Target(TYPE) @Retention(RUNTIME)
+ public @interface Entity {
+ String name() default "";
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ <xsd:element name="table" type="orm:table"
+ minOccurs="0"/>
+ <xsd:element name="secondary-table"
type="orm:secondary-table"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="primary-key-join-column"
+ type="orm:primary-key-join-column"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="id-class" type="orm:id-class"
minOccurs="0"/>
+ <xsd:element name="inheritance" type="orm:inheritance"
minOccurs="0"/>
+ <xsd:element name="discriminator-value"
type="orm:discriminator-value"
+ minOccurs="0"/>
+ <xsd:element name="discriminator-column"
+ type="orm:discriminator-column"
+ minOccurs="0"/>
+ <xsd:element name="sequence-generator"
type="orm:sequence-generator"
+ minOccurs="0"/>
+ <xsd:element name="table-generator"
type="orm:table-generator"
+ minOccurs="0"/>
+ <xsd:element name="named-query"
type="orm:named-query"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="named-native-query"
type="orm:named-native-query"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="sql-result-set-mapping"
+ type="orm:sql-result-set-mapping"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="exclude-default-listeners"
type="orm:emptyType"
+ minOccurs="0"/>
+ <xsd:element name="exclude-superclass-listeners"
type="orm:emptyType"
+ minOccurs="0"/>
+ <xsd:element name="entity-listeners"
type="orm:entity-listeners"
+ minOccurs="0"/>
+ <xsd:element name="pre-persist" type="orm:pre-persist"
minOccurs="0"/>
+ <xsd:element name="post-persist"
type="orm:post-persist"
+ minOccurs="0"/>
+ <xsd:element name="pre-remove" type="orm:pre-remove"
minOccurs="0"/>
+ <xsd:element name="post-remove" type="orm:post-remove"
minOccurs="0"/>
+ <xsd:element name="pre-update" type="orm:pre-update"
minOccurs="0"/>
+ <xsd:element name="post-update" type="orm:post-update"
minOccurs="0"/>
+ <xsd:element name="post-load" type="orm:post-load"
minOccurs="0"/>
+ <xsd:element name="attribute-override"
type="orm:attribute-override"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="association-override"
+ type="orm:association-override"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="attributes" type="orm:attributes"
minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"/>
+ <xsd:attribute name="class" type="xsd:string"
use="required"/>
+ <xsd:attribute name="access" type="orm:access-type"/>
+ <xsd:attribute name="metadata-complete"
type="xsd:boolean"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="attributes">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ This element contains the entity field or property mappings.
+ It may be sparsely populated to include only a subset of the
+ fields or properties. If metadata-complete for the entity is true
+ then the remainder of the attributes will be defaulted according
+ to the default rules.
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:choice>
+ <xsd:element name="id" type="orm:id"
+ minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="embedded-id"
type="orm:embedded-id"
+ minOccurs="0"/>
+ </xsd:choice>
+ <xsd:element name="basic" type="orm:basic"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="version" type="orm:version"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="many-to-one"
type="orm:many-to-one"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="one-to-many"
type="orm:one-to-many"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="one-to-one" type="orm:one-to-one"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="many-to-many"
type="orm:many-to-many"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="embedded" type="orm:embedded"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="transient" type="orm:transient"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:simpleType name="access-type">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ This element determines how the persistence provider accesses the
+ state of an entity or embedded object.
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="PROPERTY"/>
+ <xsd:enumeration value="FIELD"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="entity-listeners">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({TYPE}) @Retention(RUNTIME)
+ public @interface EntityListeners {
+ Class[] value();
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="entity-listener"
type="orm:entity-listener"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="entity-listener">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ Defines an entity listener to be invoked at lifecycle events
+ for the entities that list this listener.
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="pre-persist" type="orm:pre-persist"
minOccurs="0"/>
+ <xsd:element name="post-persist"
type="orm:post-persist"
+ minOccurs="0"/>
+ <xsd:element name="pre-remove" type="orm:pre-remove"
minOccurs="0"/>
+ <xsd:element name="post-remove" type="orm:post-remove"
minOccurs="0"/>
+ <xsd:element name="pre-update" type="orm:pre-update"
minOccurs="0"/>
+ <xsd:element name="post-update" type="orm:post-update"
minOccurs="0"/>
+ <xsd:element name="post-load" type="orm:post-load"
minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="class" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="pre-persist">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD}) @Retention(RUNTIME)
+ public @interface PrePersist {}
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="method-name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="post-persist">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD}) @Retention(RUNTIME)
+ public @interface PostPersist {}
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="method-name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="pre-remove">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD}) @Retention(RUNTIME)
+ public @interface PreRemove {}
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="method-name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="post-remove">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD}) @Retention(RUNTIME)
+ public @interface PostRemove {}
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="method-name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="pre-update">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD}) @Retention(RUNTIME)
+ public @interface PreUpdate {}
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="method-name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="post-update">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD}) @Retention(RUNTIME)
+ public @interface PostUpdate {}
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="method-name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="post-load">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD}) @Retention(RUNTIME)
+ public @interface PostLoad {}
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="method-name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="query-hint">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({}) @Retention(RUNTIME)
+ public @interface QueryHint {
+ String name();
+ String value();
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="value" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="named-query">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({TYPE}) @Retention(RUNTIME)
+ public @interface NamedQuery {
+ String name();
+ String query();
+ QueryHint[] hints() default {};
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="query" type="xsd:string"/>
+ <xsd:element name="hint" type="orm:query-hint"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="named-native-query">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({TYPE}) @Retention(RUNTIME)
+ public @interface NamedNativeQuery {
+ String name();
+ String query();
+ QueryHint[] hints() default {};
+ Class resultClass() default void.class;
+ String resultSetMapping() default ""; //named
SqlResultSetMapping
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="query" type="xsd:string"/>
+ <xsd:element name="hint" type="orm:query-hint"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="result-class" type="xsd:string"/>
+ <xsd:attribute name="result-set-mapping"
type="xsd:string"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="sql-result-set-mapping">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({TYPE}) @Retention(RUNTIME)
+ public @interface SqlResultSetMapping {
+ String name();
+ EntityResult[] entities() default {};
+ ColumnResult[] columns() default {};
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="entity-result"
type="orm:entity-result"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="column-result"
type="orm:column-result"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="entity-result">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({}) @Retention(RUNTIME)
+ public @interface EntityResult {
+ Class entityClass();
+ FieldResult[] fields() default {};
+ String discriminatorColumn() default "";
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="field-result"
type="orm:field-result"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="entity-class" type="xsd:string"
use="required"/>
+ <xsd:attribute name="discriminator-column"
type="xsd:string"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="field-result">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({}) @Retention(RUNTIME)
+ public @interface FieldResult {
+ String name();
+ String column();
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="column" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="column-result">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({}) @Retention(RUNTIME)
+ public @interface ColumnResult {
+ String name();
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="table">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({TYPE}) @Retention(RUNTIME)
+ public @interface Table {
+ String name() default "";
+ String catalog() default "";
+ String schema() default "";
+ UniqueConstraint[] uniqueConstraints() default {};
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="unique-constraint"
type="orm:unique-constraint"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"/>
+ <xsd:attribute name="catalog" type="xsd:string"/>
+ <xsd:attribute name="schema" type="xsd:string"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="secondary-table">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({TYPE}) @Retention(RUNTIME)
+ public @interface SecondaryTable {
+ String name();
+ String catalog() default "";
+ String schema() default "";
+ PrimaryKeyJoinColumn[] pkJoinColumns() default {};
+ UniqueConstraint[] uniqueConstraints() default {};
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="primary-key-join-column"
+ type="orm:primary-key-join-column"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="unique-constraint"
type="orm:unique-constraint"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="catalog" type="xsd:string"/>
+ <xsd:attribute name="schema" type="xsd:string"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="unique-constraint">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({}) @Retention(RUNTIME)
+ public @interface UniqueConstraint {
+ String[] columnNames();
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="column-name" type="xsd:string"
+ maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="column">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface Column {
+ String name() default "";
+ boolean unique() default false;
+ boolean nullable() default true;
+ boolean insertable() default true;
+ boolean updatable() default true;
+ String columnDefinition() default "";
+ String table() default "";
+ int length() default 255;
+ int precision() default 0; // decimal precision
+ int scale() default 0; // decimal scale
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string"/>
+ <xsd:attribute name="unique" type="xsd:boolean"/>
+ <xsd:attribute name="nullable" type="xsd:boolean"/>
+ <xsd:attribute name="insertable" type="xsd:boolean"/>
+ <xsd:attribute name="updatable" type="xsd:boolean"/>
+ <xsd:attribute name="column-definition"
type="xsd:string"/>
+ <xsd:attribute name="table" type="xsd:string"/>
+ <xsd:attribute name="length" type="xsd:int"/>
+ <xsd:attribute name="precision" type="xsd:int"/>
+ <xsd:attribute name="scale" type="xsd:int"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="join-column">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface JoinColumn {
+ String name() default "";
+ String referencedColumnName() default "";
+ boolean unique() default false;
+ boolean nullable() default true;
+ boolean insertable() default true;
+ boolean updatable() default true;
+ String columnDefinition() default "";
+ String table() default "";
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string"/>
+ <xsd:attribute name="referenced-column-name"
type="xsd:string"/>
+ <xsd:attribute name="unique" type="xsd:boolean"/>
+ <xsd:attribute name="nullable" type="xsd:boolean"/>
+ <xsd:attribute name="insertable" type="xsd:boolean"/>
+ <xsd:attribute name="updatable" type="xsd:boolean"/>
+ <xsd:attribute name="column-definition"
type="xsd:string"/>
+ <xsd:attribute name="table" type="xsd:string"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:simpleType name="generation-type">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ public enum GenerationType { TABLE, SEQUENCE, IDENTITY, AUTO };
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="TABLE"/>
+ <xsd:enumeration value="SEQUENCE"/>
+ <xsd:enumeration value="IDENTITY"/>
+ <xsd:enumeration value="AUTO"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="attribute-override">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface AttributeOverride {
+ String name();
+ Column column();
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="column" type="orm:column"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="association-override">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface AssociationOverride {
+ String name();
+ JoinColumn[] joinColumns();
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="join-column"
type="orm:join-column"
+ maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="id-class">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({TYPE}) @Retention(RUNTIME)
+ public @interface IdClass {
+ Class value();
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="class" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="id">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface Id {}
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="column" type="orm:column"
+ minOccurs="0"/>
+ <xsd:element name="generated-value"
type="orm:generated-value"
+ minOccurs="0"/>
+ <xsd:element name="temporal" type="orm:temporal"
+ minOccurs="0"/>
+ <xsd:element name="table-generator"
type="orm:table-generator"
+ minOccurs="0"/>
+ <xsd:element name="sequence-generator"
type="orm:sequence-generator"
+ minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="embedded-id">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface EmbeddedId {}
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="attribute-override"
type="orm:attribute-override"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="transient">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface Transient {}
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="version">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface Version {}
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="column" type="orm:column"
minOccurs="0"/>
+ <xsd:element name="temporal" type="orm:temporal"
minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="basic">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface Basic {
+ FetchType fetch() default EAGER;
+ boolean optional() default true;
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="column" type="orm:column"
minOccurs="0"/>
+ <xsd:choice>
+ <xsd:element name="lob" type="orm:lob"
minOccurs="0"/>
+ <xsd:element name="temporal" type="orm:temporal"
minOccurs="0"/>
+ <xsd:element name="enumerated"
type="orm:enumerated" minOccurs="0"/>
+ </xsd:choice>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="fetch" type="orm:fetch-type"/>
+ <xsd:attribute name="optional" type="xsd:boolean"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:simpleType name="fetch-type">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ public enum FetchType { LAZY, EAGER };
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="LAZY"/>
+ <xsd:enumeration value="EAGER"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="lob">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface Lob {}
+
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:simpleType name="temporal">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface Temporal {
+ TemporalType value();
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="orm:temporal-type"/>
+ </xsd:simpleType>
+
+ <!-- **************************************************** -->
+
+ <xsd:simpleType name="temporal-type">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ public enum TemporalType {
+ DATE, // java.sql.Date
+ TIME, // java.sql.Time
+ TIMESTAMP // java.sql.Timestamp
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="DATE"/>
+ <xsd:enumeration value="TIME"/>
+ <xsd:enumeration value="TIMESTAMP"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <!-- **************************************************** -->
+
+ <xsd:simpleType name="enumerated">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface Enumerated {
+ EnumType value() default ORDINAL;
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="orm:enum-type"/>
+ </xsd:simpleType>
+
+ <!-- **************************************************** -->
+
+ <xsd:simpleType name="enum-type">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ public enum EnumType {
+ ORDINAL,
+ STRING
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="ORDINAL"/>
+ <xsd:enumeration value="STRING"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="many-to-one">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface ManyToOne {
+ Class targetEntity() default void.class;
+ CascadeType[] cascade() default {};
+ FetchType fetch() default EAGER;
+ boolean optional() default true;
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:choice>
+ <xsd:element name="join-column"
type="orm:join-column"
+ minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="join-table"
type="orm:join-table"
+ minOccurs="0"/>
+ </xsd:choice>
+ <xsd:element name="cascade" type="orm:cascade-type"
+ minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="target-entity"
type="xsd:string"/>
+ <xsd:attribute name="fetch" type="orm:fetch-type"/>
+ <xsd:attribute name="optional" type="xsd:boolean"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="cascade-type">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ public enum CascadeType { ALL, PERSIST, MERGE, REMOVE, REFRESH};
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="cascade-all" type="orm:emptyType"
+ minOccurs="0"/>
+ <xsd:element name="cascade-persist"
type="orm:emptyType"
+ minOccurs="0"/>
+ <xsd:element name="cascade-merge"
type="orm:emptyType"
+ minOccurs="0"/>
+ <xsd:element name="cascade-remove"
type="orm:emptyType"
+ minOccurs="0"/>
+ <xsd:element name="cascade-refresh"
type="orm:emptyType"
+ minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="one-to-one">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface OneToOne {
+ Class targetEntity() default void.class;
+ CascadeType[] cascade() default {};
+ FetchType fetch() default EAGER;
+ boolean optional() default true;
+ String mappedBy() default "";
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:choice>
+ <xsd:element name="primary-key-join-column"
+ type="orm:primary-key-join-column"
+ minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="join-column"
type="orm:join-column"
+ minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="join-table"
type="orm:join-table"
+ minOccurs="0"/>
+ </xsd:choice>
+ <xsd:element name="cascade" type="orm:cascade-type"
+ minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="target-entity"
type="xsd:string"/>
+ <xsd:attribute name="fetch" type="orm:fetch-type"/>
+ <xsd:attribute name="optional" type="xsd:boolean"/>
+ <xsd:attribute name="mapped-by" type="xsd:string"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="one-to-many">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface OneToMany {
+ Class targetEntity() default void.class;
+ CascadeType[] cascade() default {};
+ FetchType fetch() default LAZY;
+ String mappedBy() default "";
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="order-by" type="orm:order-by"
+ minOccurs="0"/>
+ <xsd:element name="map-key" type="orm:map-key"
+ minOccurs="0"/>
+ <xsd:choice>
+ <xsd:element name="join-table"
type="orm:join-table"
+ minOccurs="0"/>
+ <xsd:element name="join-column"
type="orm:join-column"
+ minOccurs="0"
maxOccurs="unbounded"/>
+ </xsd:choice>
+ <xsd:element name="cascade" type="orm:cascade-type"
+ minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="target-entity"
type="xsd:string"/>
+ <xsd:attribute name="fetch" type="orm:fetch-type"/>
+ <xsd:attribute name="mapped-by" type="xsd:string"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="join-table">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface JoinTable {
+ String name() default "";
+ String catalog() default "";
+ String schema() default "";
+ JoinColumn[] joinColumns() default {};
+ JoinColumn[] inverseJoinColumns() default {};
+ UniqueConstraint[] uniqueConstraints() default {};
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="join-column"
type="orm:join-column"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="inverse-join-column"
type="orm:join-column"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="unique-constraint"
type="orm:unique-constraint"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"/>
+ <xsd:attribute name="catalog" type="xsd:string"/>
+ <xsd:attribute name="schema" type="xsd:string"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="many-to-many">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface ManyToMany {
+ Class targetEntity() default void.class;
+ CascadeType[] cascade() default {};
+ FetchType fetch() default LAZY;
+ String mappedBy() default "";
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="order-by" type="orm:order-by"
+ minOccurs="0"/>
+ <xsd:element name="map-key" type="orm:map-key"
+ minOccurs="0"/>
+ <xsd:element name="join-table" type="orm:join-table"
+ minOccurs="0"/>
+ <xsd:element name="cascade" type="orm:cascade-type"
+ minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="target-entity"
type="xsd:string"/>
+ <xsd:attribute name="fetch" type="orm:fetch-type"/>
+ <xsd:attribute name="mapped-by" type="xsd:string"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="generated-value">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface GeneratedValue {
+ GenerationType strategy() default AUTO;
+ String generator() default "";
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="strategy"
type="orm:generation-type"/>
+ <xsd:attribute name="generator" type="xsd:string"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="map-key">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface MapKey {
+ String name() default "";
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:simpleType name="order-by">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface OrderBy {
+ String value() default "";
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="inheritance">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({TYPE}) @Retention(RUNTIME)
+ public @interface Inheritance {
+ InheritanceType strategy() default SINGLE_TABLE;
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="strategy"
type="orm:inheritance-type"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:simpleType name="inheritance-type">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ public enum InheritanceType
+ { SINGLE_TABLE, JOINED, TABLE_PER_CLASS};
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="SINGLE_TABLE"/>
+ <xsd:enumeration value="JOINED"/>
+ <xsd:enumeration value="TABLE_PER_CLASS"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <!-- **************************************************** -->
+
+ <xsd:simpleType name="discriminator-value">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({TYPE}) @Retention(RUNTIME)
+ public @interface DiscriminatorValue {
+ String value();
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+
+ <!-- **************************************************** -->
+
+ <xsd:simpleType name="discriminator-type">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ public enum DiscriminatorType { STRING, CHAR, INTEGER };
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="STRING"/>
+ <xsd:enumeration value="CHAR"/>
+ <xsd:enumeration value="INTEGER"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="primary-key-join-column">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface PrimaryKeyJoinColumn {
+ String name() default "";
+ String referencedColumnName() default "";
+ String columnDefinition() default "";
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string"/>
+ <xsd:attribute name="referenced-column-name"
type="xsd:string"/>
+ <xsd:attribute name="column-definition"
type="xsd:string"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="discriminator-column">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({TYPE}) @Retention(RUNTIME)
+ public @interface DiscriminatorColumn {
+ String name() default "DTYPE";
+ DiscriminatorType discriminatorType() default STRING;
+ String columnDefinition() default "";
+ int length() default 31;
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string"/>
+ <xsd:attribute name="discriminator-type"
type="orm:discriminator-type"/>
+ <xsd:attribute name="column-definition"
type="xsd:string"/>
+ <xsd:attribute name="length" type="xsd:int"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="embeddable">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ Defines the settings and mappings for embeddable objects. Is
+ allowed to be sparsely populated and used in conjunction with
+ the annotations. Alternatively, the metadata-complete attribute
+ can be used to indicate that no annotations are to be processed
+ in the class. If this is the case then the defaulting rules will
+ be recursively applied.
+
+ @Target({TYPE}) @Retention(RUNTIME)
+ public @interface Embeddable {}
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ <xsd:element name="attributes"
type="orm:embeddable-attributes"
+ minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="class" type="xsd:string"
use="required"/>
+ <xsd:attribute name="access" type="orm:access-type"/>
+ <xsd:attribute name="metadata-complete"
type="xsd:boolean"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="embeddable-attributes">
+ <xsd:sequence>
+ <xsd:element name="basic" type="orm:basic"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="transient" type="orm:transient"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="embedded">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface Embedded {}
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="attribute-override"
type="orm:attribute-override"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="mapped-superclass">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ Defines the settings and mappings for a mapped superclass. Is
+ allowed to be sparsely populated and used in conjunction with
+ the annotations. Alternatively, the metadata-complete attribute
+ can be used to indicate that no annotations are to be processed
+ If this is the case then the defaulting rules will be recursively
+ applied.
+
+ @Target(TYPE) @Retention(RUNTIME)
+ public @interface MappedSuperclass{}
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ <xsd:element name="id-class" type="orm:id-class"
minOccurs="0"/>
+ <xsd:element name="exclude-default-listeners"
type="orm:emptyType"
+ minOccurs="0"/>
+ <xsd:element name="exclude-superclass-listeners"
type="orm:emptyType"
+ minOccurs="0"/>
+ <xsd:element name="entity-listeners"
type="orm:entity-listeners"
+ minOccurs="0"/>
+ <xsd:element name="pre-persist" type="orm:pre-persist"
minOccurs="0"/>
+ <xsd:element name="post-persist"
type="orm:post-persist"
+ minOccurs="0"/>
+ <xsd:element name="pre-remove" type="orm:pre-remove"
minOccurs="0"/>
+ <xsd:element name="post-remove" type="orm:post-remove"
minOccurs="0"/>
+ <xsd:element name="pre-update" type="orm:pre-update"
minOccurs="0"/>
+ <xsd:element name="post-update" type="orm:post-update"
minOccurs="0"/>
+ <xsd:element name="post-load" type="orm:post-load"
minOccurs="0"/>
+ <xsd:element name="attributes" type="orm:attributes"
minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="class" type="xsd:string"
use="required"/>
+ <xsd:attribute name="access" type="orm:access-type"/>
+ <xsd:attribute name="metadata-complete"
type="xsd:boolean"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="sequence-generator">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface SequenceGenerator {
+ String name();
+ String sequenceName() default "";
+ int initialValue() default 1;
+ int allocationSize() default 50;
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="sequence-name"
type="xsd:string"/>
+ <xsd:attribute name="initial-value" type="xsd:int"/>
+ <xsd:attribute name="allocation-size" type="xsd:int"/>
+ </xsd:complexType>
+
+ <!-- **************************************************** -->
+
+ <xsd:complexType name="table-generator">
+ <xsd:annotation>
+ <xsd:documentation>
+
+ @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME)
+ public @interface TableGenerator {
+ String name();
+ String table() default "";
+ String catalog() default "";
+ String schema() default "";
+ String pkColumnName() default "";
+ String valueColumnName() default "";
+ String pkColumnValue() default "";
+ int initialValue() default 0;
+ int allocationSize() default 50;
+ UniqueConstraint[] uniqueConstraints() default {};
+ }
+
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="unique-constraint"
type="orm:unique-constraint"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="table" type="xsd:string"/>
+ <xsd:attribute name="catalog" type="xsd:string"/>
+ <xsd:attribute name="schema" type="xsd:string"/>
+ <xsd:attribute name="pk-column-name"
type="xsd:string"/>
+ <xsd:attribute name="value-column-name"
type="xsd:string"/>
+ <xsd:attribute name="pk-column-value"
type="xsd:string"/>
+ <xsd:attribute name="initial-value" type="xsd:int"/>
+ <xsd:attribute name="allocation-size" type="xsd:int"/>
+ </xsd:complexType>
+
+</xsd:schema>
+
+
Property changes on: core/trunk/core/src/main/resources/org/hibernate/ejb/orm_1_0.xsd
___________________________________________________________________
Name: svn:mergeinfo
+
Copied: core/trunk/core/src/main/resources/org/hibernate/ejb/orm_2_0.xsd (from rev 19909,
core/trunk/annotations/src/main/resources/org/hibernate/ejb/orm_2_0.xsd)
===================================================================
--- core/trunk/core/src/main/resources/org/hibernate/ejb/orm_2_0.xsd
(rev 0)
+++ core/trunk/core/src/main/resources/org/hibernate/ejb/orm_2_0.xsd 2010-07-08 23:41:23
UTC (rev 19921)
@@ -0,0 +1,1434 @@
+<?xml version="1.0" encoding="UTF-8"?> <!-- Java Persistence
API object/relational mapping file schema -->
+<xsd:schema
targetNamespace="http://java.sun.com/xml/ns/persistence/orm"
+
xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
+
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ version="2.0">
+ <xsd:annotation>
+ <xsd:documentation>
+ @(#)orm_2_0.xsd 2.0 October 1 2009
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+This is the XML Schema for the persistence object/relational mapping file. The file may
be named "META-INF/orm.xml" in the persistence archive or it may be named some
other name which would be used to locate the file as resource on the classpath.
+Object/relational mapping files must indicate the object/relational mapping file schema
by using the persistence namespace:
+http://java.sun.com/xml/ns/persistence
+and indicate the version of the schema by using the version element as shown below:
+<entity-mappings
xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm
+http://java.sun.com/xml/ns/persistence/orm/orm_2_0.xsd" version="2.0">
+... </entity-mappings>
+]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType name="emptyType"/>
+ <xsd:simpleType name="versionType">
+ <xsd:restriction base="xsd:token">
+ <xsd:pattern value="[0-9]+(\.[0-9]+)*"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <!-- **************************************************** -->
+ <xsd:element name="entity-mappings">
+ <xsd:complexType>
+ <xsd:annotation>
+ <xsd:documentation>
+ The entity-mappings element is the root element of a mapping
+ file. It contains the following four types of elements:
+ 1. The persistence-unit-metadata element contains metadata for the
entire persistence unit. It is
+ undefined if this element occurs in multiple mapping files within the
same persistence unit.
+ 2. The package, schema, catalog and access elements apply to all of
the entity, mapped-superclass
+ and embeddable elements defined in the same file in which they
occur.
+ 3. The sequence-generator, table-generator, named-query,
named-native-query and
+ sql-result-set-mapping elements are global to the persistence unit.
It is undefined to have more
+ than one sequence-generator or table-generator of the same name in
the same or different mapping
+ files in a persistence unit. It is also undefined to have more than
one named-query,
+ named-native-query, or result-set-mapping of the same name in the
same or different mapping files in
+ a persistence unit.
+ 4. The entity, mapped-superclass and embeddable elements each define
the mapping information for a
+ managed persistent class. The mapping information contained in these
elements may be complete or it
+ may be partial.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element
+ name="description" type="xsd:string"
minOccurs="0"/>
+ <xsd:element name="persistence-unit-metadata"
type="orm:persistence-unit-metadata" minOccurs="0"/>
+ <xsd:element name="package" type="xsd:string"
minOccurs="0"/>
+ <xsd:element name="schema" type="xsd:string"
minOccurs="0"/>
+ <xsd:element name="catalog" type="xsd:string"
minOccurs="0"/>
+ <xsd:element name="access" type="orm:access-type"
minOccurs="0"/>
+ <xsd:element name="sequence-generator"
+ type="orm:sequence-generator"
+ minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xsd:element name="table-generator"
type="orm:table-generator" minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="named-query"
type="orm:named-query" minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="named-native-query"
+ type="orm:named-native-query"
+ minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xsd:element name="sql-result-set-mapping"
type="orm:sql-result-set-mapping"
+ minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="mapped-superclass"
type="orm:mapped-superclass" minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="entity" type="orm:entity"
minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="embeddable"
type="orm:embeddable" minOccurs="0"
maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="version" type="orm:versionType"
+ fixed="2.0" use="required"/>
+ </xsd:complexType>
+ </xsd:element>
+ <!-- **************************************************** -->
+ <xsd:complexType name="persistence-unit-metadata">
+ <xsd:annotation>
+ <xsd:documentation>
+ Metadata that applies to the persistence unit and not just to the mapping
file in which it is contained.
+ If the xml-mapping-metadata-complete element is specified, the complete
set of mapping metadata for the
+ persistence unit is contained in the XML mapping files for the
persistence unit.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element
+ name="description" type="xsd:string"
minOccurs="0"/>
+ <xsd:element name="xml-mapping-metadata-complete"
type="orm:emptyType" minOccurs="0"/>
+ <xsd:element name="persistence-unit-defaults"
+ type="orm:persistence-unit-defaults"
+ minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="persistence-unit-defaults">
+ <xsd:annotation>
+ <xsd:documentation>
+ These defaults are applied to the persistence unit as a whole unless they
are overridden by local
+ annotation or XML element settings.
+ schema - Used as the schema for all tables, secondary tables, join
tables, collection tables, sequence
+ generators, and table generators that apply to the persistence unit
+ catalog - Used as the catalog for all tables, secondary tables, join
tables, collection tables, sequence
+ generators, and table generators that apply to the persistence unit
+ delimited-identifiers - Used to treat database identifiers as delimited
identifiers.
+ access - Used as the access type for all managed classes in the
persistence unit
+ cascade-persist - Adds cascade-persist to the set of cascade options in
all entity relationships of the
+ persistence unit
+ entity-listeners - List of default entity listeners to be invoked on each
entity in the persistence
+ unit.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ <xsd:element name="schema" type="xsd:string"
minOccurs="0"/>
+ <xsd:element name="catalog"
+ type="xsd:string"
+ minOccurs="0"/>
+ <xsd:element name="delimited-identifiers"
type="orm:emptyType" minOccurs="0"/>
+ <xsd:element name="access"
+ type="orm:access-type" minOccurs="0"/>
+ <xsd:element name="cascade-persist"
type="orm:emptyType" minOccurs="0"/>
+ <xsd:element name="entity-listeners"
type="orm:entity-listeners" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="entity">
+ <xsd:annotation>
+ <xsd:documentation>
+ Defines the settings and mappings for an entity. Is allowed to be
sparsely populated and used in
+ conjunction
+ with the annotations. Alternatively, the metadata-complete attribute can
be used to indicate that no
+ annotations
+ on the entity class (and its fields or properties) are to be processed.
If this is the case then
+ the defaulting rules for the entity and its subelements will be
recursively applied.
+ @Target(TYPE) @Retention(RUNTIME) public @interface Entity { String
name() default "";
+ }
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element
+ name="description" type="xsd:string"
minOccurs="0"/>
+ <xsd:element name="table" type="orm:table"
minOccurs="0"/>
+ <xsd:element name="secondary-table"
type="orm:secondary-table" minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xsd:element name="primary-key-join-column"
type="orm:primary-key-join-column"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="id-class" type="orm:id-class"
minOccurs="0"/>
+ <xsd:element name="inheritance"
+ type="orm:inheritance" minOccurs="0"/>
+ <xsd:element name="discriminator-value"
type="orm:discriminator-value" minOccurs="0"/>
+ <xsd:element name="discriminator-column"
type="orm:discriminator-column" minOccurs="0"/>
+ <xsd:element name="sequence-generator"
+ type="orm:sequence-generator"
minOccurs="0"/>
+ <xsd:element name="table-generator"
type="orm:table-generator" minOccurs="0"/>
+ <xsd:element name="named-query" type="orm:named-query"
minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="named-native-query"
+ type="orm:named-native-query" minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="sql-result-set-mapping"
+ type="orm:sql-result-set-mapping"
minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="exclude-default-listeners"
+ type="orm:emptyType" minOccurs="0"/>
+ <xsd:element name="exclude-superclass-listeners"
type="orm:emptyType" minOccurs="0"/>
+ <xsd:element name="entity-listeners"
type="orm:entity-listeners" minOccurs="0"/>
+ <xsd:element name="pre-persist"
type="orm:pre-persist"
+ minOccurs="0"/>
+ <xsd:element name="post-persist"
type="orm:post-persist" minOccurs="0"/>
+ <xsd:element name="pre-remove" type="orm:pre-remove"
+ minOccurs="0"/>
+ <xsd:element name="post-remove" type="orm:post-remove"
minOccurs="0"/>
+ <xsd:element name="pre-update" type="orm:pre-update"
+ minOccurs="0"/>
+ <xsd:element name="post-update" type="orm:post-update"
minOccurs="0"/>
+ <xsd:element name="post-load" type="orm:post-load"
+ minOccurs="0"/>
+ <xsd:element name="attribute-override"
type="orm:attribute-override" minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="association-override"
type="orm:association-override"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="attributes" type="orm:attributes"
minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"/>
+ <xsd:attribute name="class" type="xsd:string"
use="required"/>
+ <xsd:attribute name="access" type="orm:access-type"/>
+ <xsd:attribute name="cacheable" type="xsd:boolean"/>
+ <xsd:attribute name="metadata-complete"
type="xsd:boolean"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:simpleType name="access-type">
+ <xsd:annotation>
+ <xsd:documentation>
+ This element determines how the persistence provider accesses the state
of an entity or embedded object.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="PROPERTY"/>
+ <xsd:enumeration value="FIELD"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="association-override">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface
AssociationOverride {
+ }
+ String name(); JoinColumn[] joinColumns() default{}; JoinTable
joinTable() default @JoinTable;
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ <xsd:choice>
+ <xsd:element
+ name="join-column" type="orm:join-column"
minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="join-table"
type="orm:join-table" minOccurs="0"/>
+ </xsd:choice>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="attribute-override">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface
AttributeOverride {
+ String name(); Column column();
+ }
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ <xsd:element name="column" type="orm:column"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="attributes">
+ <xsd:annotation>
+ <xsd:documentation>
+ This element contains the entity field or property mappings. It may be
sparsely populated to include
+ only a
+ subset of the fields or properties. If metadata-complete for the entity
is true then the remainder of
+ the
+ attributes will be defaulted according to the default rules.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ <xsd:choice>
+ <xsd:element name="id" type="orm:id"
minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="embedded-id"
type="orm:embedded-id"
+ minOccurs="0"/>
+ </xsd:choice>
+ <xsd:element
+ name="basic" type="orm:basic"
minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="version" type="orm:version"
minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="many-to-one"
+ type="orm:many-to-one"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="one-to-many" type="orm:one-to-many"
minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xsd:element name="one-to-one" type="orm:one-to-one"
minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="many-to-many"
type="orm:many-to-many" minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="element-collection"
+ type="orm:element-collection" minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="embedded" type="orm:embedded"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="transient" type="orm:transient"
minOccurs="0"
+ maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="basic">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Basic {
+ FetchType fetch() default EAGER; boolean optional() default true;
+ }
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="column" type="orm:column"
minOccurs="0"/>
+ <xsd:choice>
+ <xsd:element name="lob" type="orm:lob"
minOccurs="0"/>
+ <xsd:element name="temporal" type="orm:temporal"
minOccurs="0"/>
+ <xsd:element name="enumerated"
type="orm:enumerated" minOccurs="0"/>
+ </xsd:choice>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="fetch" type="orm:fetch-type"/>
+ <xsd:attribute name="optional" type="xsd:boolean"/>
+ <xsd:attribute name="access" type="orm:access-type"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="cascade-type">
+ <xsd:annotation>
+ <xsd:documentation>
+ public enum CascadeType { ALL, PERSIST, MERGE, REMOVE, REFRESH, DETACH};
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element
+ name="cascade-all" type="orm:emptyType"
minOccurs="0"/>
+ <xsd:element name="cascade-persist"
type="orm:emptyType" minOccurs="0"/>
+ <xsd:element name="cascade-merge" type="orm:emptyType"
minOccurs="0"/>
+ <xsd:element name="cascade-remove"
type="orm:emptyType"
+ minOccurs="0"/>
+ <xsd:element name="cascade-refresh"
type="orm:emptyType" minOccurs="0"/>
+ <xsd:element name="cascade-detach"
type="orm:emptyType"
+ minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="collection-table">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface
CollectionTable {
+ }
+ String name() default ""; String catalog() default
""; String schema() default ""; JoinColumn[]
+ joinColumns()
+ default {}; UniqueConstraint[] uniqueConstraints() default {};
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="join-column" type="orm:join-column"
minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="unique-constraint"
type="orm:unique-constraint" minOccurs="0"
maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"/>
+ <xsd:attribute name="catalog" type="xsd:string"/>
+ <xsd:attribute name="schema" type="xsd:string"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="column">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Column {
+ }
+ String name() default ""; boolean unique() default false;
boolean nullable() default true; boolean
+ insertable()
+ default true; boolean updatable() default true; String columnDefinition()
default ""; String table()
+ default "";
+ int length() default 255; int precision() default 0; // decimal precision
int scale() default 0; //
+ decimal
+ scale
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string"/>
+ <xsd:attribute name="unique" type="xsd:boolean"/>
+ <xsd:attribute name="nullable" type="xsd:boolean"/>
+ <xsd:attribute name="insertable" type="xsd:boolean"/>
+ <xsd:attribute name="updatable" type="xsd:boolean"/>
+ <xsd:attribute name="column-definition"
type="xsd:string"/>
+ <xsd:attribute name="table" type="xsd:string"/>
+ <xsd:attribute name="length" type="xsd:int"/>
+ <xsd:attribute name="precision" type="xsd:int"/>
+ <xsd:attribute name="scale" type="xsd:int"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="column-result">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({}) @Retention(RUNTIME) public @interface ColumnResult {
+ }
+ String name();
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="discriminator-column">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({TYPE}) @Retention(RUNTIME) public @interface DiscriminatorColumn
{
+ String name() default "DTYPE"; DiscriminatorType
discriminatorType() default STRING; String
+ columnDefinition()
+ default ""; int length() default 31;
+ }
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string"/>
+ <xsd:attribute name="discriminator-type"
type="orm:discriminator-type"/>
+ <xsd:attribute name="column-definition"
type="xsd:string"/>
+ <xsd:attribute name="length" type="xsd:int"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:simpleType name="discriminator-type">
+ <xsd:annotation>
+ <xsd:documentation>public enum DiscriminatorType { STRING, CHAR,
INTEGER };
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="STRING"/>
+ <xsd:enumeration value="CHAR"/>
+ <xsd:enumeration value="INTEGER"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <!-- **************************************************** -->
+ <xsd:simpleType name="discriminator-value">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({TYPE}) @Retention(RUNTIME) public @interface DiscriminatorValue
{
+ }
+ String value();
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="element-collection">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface
ElementCollection {
+ }
+ Class targetClass() default void.class; FetchType fetch() default LAZY;
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:choice>
+ <xsd:element
+ name="order-by" type="orm:order-by"
minOccurs="0"/>
+ <xsd:element name="order-column"
type="orm:order-column" minOccurs="0"/>
+ </xsd:choice>
+ <xsd:choice>
+ <xsd:element name="map-key" type="orm:map-key"
+ minOccurs="0"/>
+ <xsd:sequence>
+ <xsd:element name="map-key-class"
type="orm:map-key-class" minOccurs="0"/>
+ <xsd:choice>
+ <xsd:element name="map-key-temporal"
type="orm:temporal" minOccurs="0"/>
+ <xsd:element name="map-key-enumerated"
+ type="orm:enumerated"
+ minOccurs="0"/>
+ <xsd:element name="map-key-attribute-override"
type="orm:attribute-override" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </xsd:choice>
+ <xsd:choice>
+ <xsd:element name="map-key-column"
type="orm:map-key-column" minOccurs="0"/>
+ <xsd:element name="map-key-join-column"
+ type="orm:map-key-join-column"
minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:sequence>
+ </xsd:choice>
+ <xsd:choice>
+
+ <xsd:sequence>
+ <xsd:element name="column" type="orm:column"
minOccurs="0"/>
+ <xsd:choice>
+ <xsd:element name="temporal"
type="orm:temporal" minOccurs="0"/>
+ <xsd:element name="enumerated"
type="orm:enumerated" minOccurs="0"/>
+ <xsd:element name="lob" type="orm:lob"
+ minOccurs="0"/>
+ </xsd:choice>
+ </xsd:sequence>
+ <xsd:sequence>
+ <xsd:element name="attribute-override"
+ type="orm:attribute-override"
+ minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xsd:element name="association-override"
+ type="orm:association-override"
+ minOccurs="0"
+ maxOccurs="unbounded"/>
+
+
+ </xsd:sequence>
+ </xsd:choice>
+ <xsd:element name="collection-table"
type="orm:collection-table"
+ minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="target-class" type="xsd:string"/>
+ <xsd:attribute name="fetch" type="orm:fetch-type"/>
+ <xsd:attribute name="access" type="orm:access-type"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="embeddable">
+ <xsd:annotation>
+ <xsd:documentation>
+ Defines the settings and mappings for embeddable objects. Is allowed to
be sparsely populated and used
+ in
+ conjunction with
+ the annotations. Alternatively, the metadata-complete attribute can be
used to indicate that no
+ annotations are
+ to be processed in the class. If this is the case then the defaulting
rules will be recursively applied.
+ @Target({TYPE}) @Retention(RUNTIME) public @interface Embeddable {}
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ <xsd:element name="attributes"
type="orm:embeddable-attributes"
+ minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="class" type="xsd:string"
use="required"/>
+ <xsd:attribute name="access" type="orm:access-type"/>
+ <xsd:attribute name="metadata-complete"
type="xsd:boolean"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="embeddable-attributes">
+ <xsd:sequence>
+ <xsd:element name="basic" type="orm:basic"
minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="many-to-one"
type="orm:many-to-one"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="one-to-many" type="orm:one-to-many"
minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xsd:element name="one-to-one" type="orm:one-to-one"
minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="many-to-many"
+ type="orm:many-to-many" minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="element-collection"
+ type="orm:element-collection"
+ minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="embedded" type="orm:embedded"
minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="transient" type="orm:transient"
minOccurs="0" maxOccurs="unbounded"/>
+
+ </xsd:sequence>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="embedded">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Embedded
{}
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="attribute-override"
type="orm:attribute-override" minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element
+
+ name="association-override"
type="orm:association-override"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="access" type="orm:access-type"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="embedded-id">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface EmbeddedId
{}
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="attribute-override"
type="orm:attribute-override" minOccurs="0"
maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="access" type="orm:access-type"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="entity-listener">
+ <xsd:annotation>
+ <xsd:documentation>
+ Defines an entity listener to be invoked at lifecycle events for the
entities that list this listener.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ <xsd:element name="pre-persist" type="orm:pre-persist"
minOccurs="0"/>
+ <xsd:element name="post-persist"
type="orm:post-persist" minOccurs="0"/>
+ <xsd:element name="pre-remove" type="orm:pre-remove"
minOccurs="0"/>
+ <xsd:element name="post-remove"
type="orm:post-remove"
+ minOccurs="0"/>
+ <xsd:element name="pre-update" type="orm:pre-update"
minOccurs="0"/>
+ <xsd:element name="post-update"
+ type="orm:post-update" minOccurs="0"/>
+ <xsd:element name="post-load" type="orm:post-load"
minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="class" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="entity-listeners">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({TYPE}) @Retention(RUNTIME) public @interface EntityListeners {
+ }
+ Class[] value();
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="entity-listener"
type="orm:entity-listener" minOccurs="0"
maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="entity-result">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({}) @Retention(RUNTIME) public @interface EntityResult {
+ }
+ Class entityClass(); FieldResult[] fields() default {}; String
discriminatorColumn() default "";
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="field-result"
type="orm:field-result" minOccurs="0"
maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="entity-class" type="xsd:string"
use="required"/>
+ <xsd:attribute name="discriminator-column"
type="xsd:string"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:simpleType name="enum-type">
+ <xsd:annotation>
+ <xsd:documentation>
+ public enum EnumType { ORDINAL,
+ }
+ STRING
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="ORDINAL"/>
+ <xsd:enumeration value="STRING"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <!-- **************************************************** -->
+ <xsd:simpleType name="enumerated">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Enumerated
{
+ }
+ EnumType value() default ORDINAL;
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="orm:enum-type"/>
+ </xsd:simpleType>
+ <!-- **************************************************** -->
+ <xsd:simpleType name="fetch-type">
+ <xsd:annotation>
+ <xsd:documentation>public enum FetchType { LAZY, EAGER };
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="LAZY"/>
+ <xsd:enumeration value="EAGER"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="field-result">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({}) @Retention(RUNTIME) public @interface FieldResult {
+ }
+ String name(); String column();
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="column" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="generated-value">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface
GeneratedValue {
+ }
+ GenerationType strategy() default AUTO; String generator() default
"";
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="strategy"
type="orm:generation-type"/>
+ <xsd:attribute name="generator" type="xsd:string"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:simpleType name="generation-type">
+ <xsd:annotation>
+ <xsd:documentation>public enum GenerationType { TABLE, SEQUENCE,
IDENTITY, AUTO };
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="TABLE"/>
+ <xsd:enumeration value="SEQUENCE"/>
+ <xsd:enumeration value="IDENTITY"/>
+ <xsd:enumeration value="AUTO"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <!-- **************************************************** -->
+ <xsd:complexType name="id">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Id {}
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element
+ name="column" type="orm:column"
minOccurs="0"/>
+ <xsd:element name="generated-value"
type="orm:generated-value" minOccurs="0"/>
+ <xsd:element name="temporal" type="orm:temporal"
minOccurs="0"/>
+ <xsd:element name="table-generator"
type="orm:table-generator"
+ minOccurs="0"/>
+ <xsd:element name="sequence-generator"
type="orm:sequence-generator"
+ minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="access" type="orm:access-type"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="id-class">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({TYPE}) @Retention(RUNTIME) public @interface IdClass {
+ }
+ Class value();
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="class" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="inheritance">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({TYPE}) @Retention(RUNTIME) public @interface Inheritance {
+ }
+ InheritanceType strategy() default SINGLE_TABLE;
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="strategy"
type="orm:inheritance-type"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:simpleType name="inheritance-type">
+ <xsd:annotation>
+ <xsd:documentation>
+ public enum InheritanceType { SINGLE_TABLE, JOINED, TABLE_PER_CLASS};
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="SINGLE_TABLE"/>
+ <xsd:enumeration value="JOINED"/>
+ <xsd:enumeration value="TABLE_PER_CLASS"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="join-column">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface JoinColumn
{
+ }
+ String name() default ""; String referencedColumnName() default
""; boolean unique() default false;
+ boolean
+ nullable() default true; boolean insertable() default true; boolean
updatable() default true; String
+ columnDefinition() default ""; String table() default
"";
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string"/>
+ <xsd:attribute name="referenced-column-name"
type="xsd:string"/>
+ <xsd:attribute name="unique" type="xsd:boolean"/>
+ <xsd:attribute name="nullable" type="xsd:boolean"/>
+ <xsd:attribute name="insertable" type="xsd:boolean"/>
+ <xsd:attribute name="updatable" type="xsd:boolean"/>
+ <xsd:attribute name="column-definition"
type="xsd:string"/>
+ <xsd:attribute name="table" type="xsd:string"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="join-table">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface JoinTable
{
+ }
+ String name() default ""; String catalog() default
""; String schema() default ""; JoinColumn[]
+ joinColumns()
+ default {}; JoinColumn[] inverseJoinColumns() default {};
UniqueConstraint[] uniqueConstraints() default
+ {};
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="join-column" type="orm:join-column"
minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element name="inverse-join-column"
type="orm:join-column" minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="unique-constraint"
type="orm:unique-constraint" minOccurs="0"
maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"/>
+ <xsd:attribute name="catalog" type="xsd:string"/>
+ <xsd:attribute name="schema" type="xsd:string"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="lob">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Lob {}
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:simpleType name="lock-mode-type">
+ <xsd:annotation>
+ <xsd:documentation>
+ public enum LockModeType { READ, WRITE, OPTIMISTIC,
OPTIMISTIC_FORCE_INCREMENT, PESSIMISTIC_READ,
+ PESSIMISTIC_WRITE, PESSIMISTIC_FORCE_INCREMENT, NONE};
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="READ"/>
+ <xsd:enumeration value="WRITE"/>
+ <xsd:enumeration value="OPTIMISTIC"/>
+ <xsd:enumeration value="OPTIMISTIC_FORCE_INCREMENT"/>
+ <xsd:enumeration value="PESSIMISTIC_READ"/>
+ <xsd:enumeration value="PESSIMISTIC_WRITE"/>
+ <xsd:enumeration value="PESSIMISTIC_FORCE_INCREMENT"/>
+ <xsd:enumeration value="NONE"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <!-- **************************************************** -->
+ <xsd:complexType name="many-to-many">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface ManyToMany
{
+ }
+ Class targetEntity() default void.class; CascadeType[] cascade() default
{}; FetchType fetch() default
+ LAZY;
+ String mappedBy() default "";
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:choice>
+ <xsd:element name="order-by" type="orm:order-by"
+ minOccurs="0"/>
+ <xsd:element name="order-column"
type="orm:order-column"
+ minOccurs="0"/>
+ </xsd:choice>
+ <xsd:choice>
+ <xsd:element name="map-key" type="orm:map-key"
+ minOccurs="0"/>
+ <xsd:sequence>
+ <xsd:element name="map-key-class"
type="orm:map-key-class" minOccurs="0"/>
+ <xsd:choice>
+ <xsd:element name="map-key-temporal"
type="orm:temporal" minOccurs="0"/>
+ <xsd:element name="map-key-enumerated"
+ type="orm:enumerated"
minOccurs="0"/>
+ <xsd:element name="map-key-attribute-override"
type="orm:attribute-override"
+ minOccurs="0"
maxOccurs="unbounded"/>
+ </xsd:choice>
+ <xsd:choice>
+ <xsd:element name="map-key-join-column"
+ type="orm:map-key-join-column"
+ minOccurs="0"
+ maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:sequence>
+ </xsd:choice>
+ <xsd:element name="join-table" type="orm:join-table"
+ minOccurs="0"/>
+ <xsd:element name="cascade" type="orm:cascade-type"
+ minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="target-entity"
type="xsd:string"/>
+ <xsd:attribute name="fetch" type="orm:fetch-type"/>
+ <xsd:attribute name="access" type="orm:access-type"/>
+ <xsd:attribute name="mapped-by" type="xsd:string"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="many-to-one">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface ManyToOne
{
+
+ name="map-key-column" type="orm:map-key-column"
+ }
+ Class targetEntity() default void.class; CascadeType[] cascade() default
{}; FetchType fetch() default
+ EAGER;
+ boolean optional() default true;
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:choice>
+ <xsd:element name="join-column"
type="orm:join-column"
+ minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="join-table"
type="orm:join-table"
+ minOccurs="0"/>
+ </xsd:choice>
+ <xsd:element name="cascade" type="orm:cascade-type"
+ minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="target-entity"
type="xsd:string"/>
+ <xsd:attribute name="fetch" type="orm:fetch-type"/>
+ <xsd:attribute name="optional" type="xsd:boolean"/>
+ <xsd:attribute name="access" type="orm:access-type"/>
+ <xsd:attribute name="maps-id" type="xsd:string"/>
+ <xsd:attribute name="id" type="xsd:boolean"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="map-key">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface MapKey {
+ }
+ String name() default "";
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="map-key-class">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface
MapKeyClass {
+ }
+ Class value();
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="class" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="map-key-column">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface
MapKeyColumn {
+ }
+ String name() default ""; boolean unique() default false;
boolean nullable() default false; boolean
+ insertable()
+ default true; boolean updatable() default true; String columnDefinition()
default ""; String table()
+ default "";
+ int length() default 255; int precision() default 0; // decimal precision
int scale() default 0; //
+ decimal
+ scale
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string"/>
+ <xsd:attribute name="unique" type="xsd:boolean"/>
+ <xsd:attribute name="nullable" type="xsd:boolean"/>
+ <xsd:attribute name="insertable" type="xsd:boolean"/>
+ <xsd:attribute name="updatable" type="xsd:boolean"/>
+ <xsd:attribute name="column-definition"
type="xsd:string"/>
+ <xsd:attribute name="table" type="xsd:string"/>
+ <xsd:attribute name="length" type="xsd:int"/>
+ <xsd:attribute name="precision" type="xsd:int"/>
+ <xsd:attribute name="scale" type="xsd:int"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="map-key-join-column">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface
MapKeyJoinColumn {
+ }
+ String name() default ""; String referencedColumnName() default
""; boolean unique() default false;
+ boolean
+ nullable() default false; boolean insertable() default true; boolean
updatable() default true; String
+ columnDefinition() default ""; String table() default
"";
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string"/>
+ <xsd:attribute name="referenced-column-name"
type="xsd:string"/>
+ <xsd:attribute name="unique" type="xsd:boolean"/>
+ <xsd:attribute name="nullable" type="xsd:boolean"/>
+ <xsd:attribute name="insertable" type="xsd:boolean"/>
+ <xsd:attribute name="updatable" type="xsd:boolean"/>
+ <xsd:attribute name="column-definition"
type="xsd:string"/>
+ <xsd:attribute name="table" type="xsd:string"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="mapped-superclass">
+ <xsd:annotation>
+ <xsd:documentation>
+ Defines the settings and mappings for a mapped superclass. Is allowed to
be sparsely populated and used
+ in
+ conjunction with the annotations. Alternatively, the metadata-complete
attribute can be used to indicate
+ that no
+ annotations are to be processed If this is the case then the defaulting
rules will be recursively
+ applied.
+ @Target(TYPE) @Retention(RUNTIME) public @interface MappedSuperclass{}
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ <xsd:element name="id-class" type="orm:id-class"
minOccurs="0"/>
+ <xsd:element name="exclude-default-listeners"
type="orm:emptyType"
+ minOccurs="0"/>
+ <xsd:element name="exclude-superclass-listeners"
type="orm:emptyType" minOccurs="0"/>
+ <xsd:element name="entity-listeners"
+ type="orm:entity-listeners"
minOccurs="0"/>
+ <xsd:element name="pre-persist" type="orm:pre-persist"
minOccurs="0"/>
+ <xsd:element name="post-persist"
type="orm:post-persist"
+ minOccurs="0"/>
+ <xsd:element name="pre-remove" type="orm:pre-remove"
minOccurs="0"/>
+ <xsd:element name="post-remove"
type="orm:post-remove"
+ minOccurs="0"/>
+ <xsd:element name="pre-update" type="orm:pre-update"
minOccurs="0"/>
+ <xsd:element name="post-update"
type="orm:post-update"
+ minOccurs="0"/>
+ <xsd:element name="post-load" type="orm:post-load"
minOccurs="0"/>
+
+ <xsd:element name="attributes" type="orm:attributes"
minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="class" type="xsd:string"
use="required"/>
+ <xsd:attribute name="access" type="orm:access-type"/>
+ <xsd:attribute name="metadata-complete"
type="xsd:boolean"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="named-native-query">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({TYPE}) @Retention(RUNTIME) public @interface NamedNativeQuery {
+ }
+ String name(); String query(); QueryHint[] hints() default {}; Class
resultClass() default void.class;
+ String
+ resultSetMapping() default ""; //named SqlResultSetMapping
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ <xsd:element name="query" type="xsd:string"/>
+ <xsd:element name="hint" type="orm:query-hint"
minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="result-class" type="xsd:string"/>
+ <xsd:attribute name="result-set-mapping"
type="xsd:string"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="named-query">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({TYPE}) @Retention(RUNTIME) public @interface NamedQuery {
+ }
+ String name(); String query(); LockModeType lockMode() default NONE;
QueryHint[] hints() default {};
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ <xsd:element name="query" type="xsd:string"/>
+ <xsd:element name="lock-mode"
type="orm:lock-mode-type" minOccurs="0"/>
+ <xsd:element name="hint"
+ type="orm:query-hint"
+ minOccurs="0" maxOccurs="unbounded"/>
+
+
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="one-to-many">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface OneToMany
{
+ }
+ Class targetEntity() default void.class; CascadeType[] cascade() default
{}; FetchType fetch() default
+ LAZY;
+ String mappedBy() default "";
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:choice>
+ <xsd:element name="order-by" type="orm:order-by"
+ minOccurs="0"/>
+ <xsd:element name="order-column"
type="orm:order-column" minOccurs="0"/>
+ </xsd:choice>
+ <xsd:choice>
+
+ <xsd:element name="map-key" type="orm:map-key"
minOccurs="0"/>
+ <xsd:sequence>
+ <xsd:element name="map-key-class"
type="orm:map-key-class"
+ minOccurs="0"/>
+ <xsd:choice>
+ <xsd:element name="map-key-temporal"
type="orm:temporal" minOccurs="0"/>
+ <xsd:element name="map-key-enumerated"
+ type="orm:enumerated"
minOccurs="0"/>
+ <xsd:element name="map-key-attribute-override"
type="orm:attribute-override"
+ minOccurs="0"
maxOccurs="unbounded"/>
+ </xsd:choice>
+ <xsd:choice>
+ <xsd:element name="map-key-column"
type="orm:map-key-column" minOccurs="0"/>
+ <xsd:element name="map-key-join-column"
+ type="orm:map-key-join-column"
+ minOccurs="0"
+ maxOccurs="unbounded"/>
+ </xsd:choice>
+ </xsd:sequence>
+
+ </xsd:choice>
+ <xsd:choice>
+
+ </xsd:choice>
+ <xsd:choice>
+ <xsd:element name="join-table"
type="orm:join-table" minOccurs="0"/>
+ <xsd:element name="join-column"
type="orm:join-column" minOccurs="0"
maxOccurs="unbounded"/>
+
+
+ </xsd:choice>
+ <xsd:element name="cascade" type="orm:cascade-type"
+ minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="target-entity"
type="xsd:string"/>
+ <xsd:attribute name="fetch" type="orm:fetch-type"/>
+ <xsd:attribute name="access" type="orm:access-type"/>
+ <xsd:attribute name="mapped-by" type="xsd:string"/>
+ <xsd:attribute name="orphan-removal"
type="xsd:boolean"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="one-to-one">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface OneToOne
{
+ }
+ Class targetEntity() default void.class; CascadeType[] cascade() default
{}; FetchType fetch() default
+ EAGER;
+ boolean optional() default true;
+ String mappedBy() default ""; boolean orphanRemoval() default
false;
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:choice>
+ <xsd:element name="primary-key-join-column"
+ type="orm:primary-key-join-column"
+ minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xsd:element name="join-column"
type="orm:join-column" minOccurs="0"
maxOccurs="unbounded"/>
+ <xsd:element name="join-table"
+ type="orm:join-table"
minOccurs="0"/>
+ </xsd:choice>
+ <xsd:element name="cascade" type="orm:cascade-type"
+ minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute
+ name="target-entity" type="xsd:string"/>
+ <xsd:attribute name="fetch" type="orm:fetch-type"/>
+ <xsd:attribute name="optional" type="xsd:boolean"/>
+ <xsd:attribute
+ name="access" type="orm:access-type"/>
+ <xsd:attribute name="mapped-by" type="xsd:string"/>
+ <xsd:attribute name="orphan-removal"
type="xsd:boolean"/>
+ <xsd:attribute
+ name="maps-id" type="xsd:string"/>
+ <xsd:attribute
+ name="id" type="xsd:boolean"/>
+
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:simpleType name="order-by">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface OrderBy {
+ }
+ String value() default "";
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="order-column">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface
OrderColumn {
+ String name() default ""; boolean nullable() default true;
boolean insertable() default true; boolean
+ updatable() default true; String columnDefinition() default
"";
+ }
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string"/>
+ <xsd:attribute name="nullable" type="xsd:boolean"/>
+ <xsd:attribute name="insertable" type="xsd:boolean"/>
+ <xsd:attribute name="updatable" type="xsd:boolean"/>
+ <xsd:attribute name="column-definition"
type="xsd:string"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="post-load">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD}) @Retention(RUNTIME) public @interface PostLoad {}
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="method-name"
+
+ type="xsd:string" use="required"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="post-persist">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD}) @Retention(RUNTIME) public @interface PostPersist {}
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="method-name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="post-remove">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD}) @Retention(RUNTIME) public @interface PostRemove {}
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="method-name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="post-update">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD}) @Retention(RUNTIME) public @interface PostUpdate {}
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="method-name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="pre-persist">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD}) @Retention(RUNTIME) public @interface PrePersist {}
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="method-name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="pre-remove">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD}) @Retention(RUNTIME) public @interface PreRemove {}
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="method-name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="pre-update">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD}) @Retention(RUNTIME) public @interface PreUpdate {}
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="method-name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="primary-key-join-column">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface
PrimaryKeyJoinColumn {
+ }
+ String name() default ""; String referencedColumnName() default
""; String columnDefinition() default
+ "";
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string"/>
+ <xsd:attribute name="referenced-column-name"
type="xsd:string"/>
+ <xsd:attribute name="column-definition"
type="xsd:string"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="query-hint">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({}) @Retention(RUNTIME) public @interface QueryHint {
+ }
+ String name(); String value();
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="value" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="secondary-table">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({TYPE}) @Retention(RUNTIME) public @interface SecondaryTable {
+ String name(); String catalog() default ""; String schema()
default ""; PrimaryKeyJoinColumn[]
+ pkJoinColumns()
+ default {}; UniqueConstraint[] uniqueConstraints() default {};
+ }
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="primary-key-join-column"
+ type="orm:primary-key-join-column"
+ minOccurs="0"
+ maxOccurs="unbounded"/>
+ <xsd:element
+
+ name="unique-constraint"
type="orm:unique-constraint" minOccurs="0"
maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="catalog" type="xsd:string"/>
+ <xsd:attribute name="schema" type="xsd:string"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="sequence-generator">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface
SequenceGenerator {
+ }
+ String name(); String sequenceName() default ""; String
catalog() default ""; String schema() default
+ ""; int
+ initialValue() default 1; int allocationSize() default 50;
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="sequence-name"
type="xsd:string"/>
+ <xsd:attribute name="catalog" type="xsd:string"/>
+ <xsd:attribute name="schema" type="xsd:string"/>
+ <xsd:attribute name="initial-value" type="xsd:int"/>
+ <xsd:attribute name="allocation-size" type="xsd:int"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="sql-result-set-mapping">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({TYPE}) @Retention(RUNTIME) public @interface SqlResultSetMapping
{
+ }
+ String name(); EntityResult[] entities() default {}; ColumnResult[]
columns() default {};
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ <xsd:element
+ name="entity-result" type="orm:entity-result"
minOccurs="0" maxOccurs="unbounded"/>
+ <xsd:element
+ name="column-result"
+ type="orm:column-result" minOccurs="0"
maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="table">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({TYPE}) @Retention(RUNTIME) public @interface Table {
+ String name() default "";
+ String catalog() default ""; String schema() default
""; UniqueConstraint[] uniqueConstraints() default
+ {};
+ }
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="unique-constraint"
type="orm:unique-constraint" minOccurs="0"
maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"/>
+ <xsd:attribute name="catalog" type="xsd:string"/>
+ <xsd:attribute name="schema" type="xsd:string"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="table-generator">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) public @interface
TableGenerator {
+ }
+ String name(); String table() default ""; String catalog()
default ""; String schema() default "";
+ String
+ pkColumnName() default ""; String valueColumnName() default
""; String pkColumnValue() default ""; int
+ initialValue() default 0; int allocationSize() default 50;
UniqueConstraint[] uniqueConstraints()
+ default {};
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="description" type="xsd:string"
minOccurs="0"/>
+ <xsd:element name="unique-constraint"
type="orm:unique-constraint"
+ minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="table" type="xsd:string"/>
+ <xsd:attribute name="catalog" type="xsd:string"/>
+ <xsd:attribute name="schema" type="xsd:string"/>
+ <xsd:attribute name="pk-column-name"
type="xsd:string"/>
+ <xsd:attribute name="value-column-name"
type="xsd:string"/>
+ <xsd:attribute name="pk-column-value"
type="xsd:string"/>
+ <xsd:attribute name="initial-value" type="xsd:int"/>
+ <xsd:attribute name="allocation-size" type="xsd:int"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:simpleType name="temporal">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Temporal
{
+ TemporalType value(); }
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="orm:temporal-type"/>
+ </xsd:simpleType>
+ <!-- **************************************************** -->
+ <xsd:simpleType name="temporal-type">
+ <xsd:annotation>
+ <xsd:documentation>
+ public enum TemporalType { DATE, // java.sql.Date TIME, // java.sql.Time
TIMESTAMP // java.sql.Timestamp
+ }
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:restriction base="xsd:token">
+ <xsd:enumeration value="DATE"/>
+ <xsd:enumeration value="TIME"/>
+ <xsd:enumeration value="TIMESTAMP"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="transient">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Transient
{}
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="unique-constraint">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({}) @Retention(RUNTIME) public @interface UniqueConstraint {
+ }
+ String name() default ""; String[] columnNames();
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="column-name" type="xsd:string"
maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"/>
+ </xsd:complexType>
+ <!-- **************************************************** -->
+ <xsd:complexType name="version">
+ <xsd:annotation>
+ <xsd:documentation>
+ @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface Version
{}
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:element name="column" type="orm:column"
minOccurs="0"/>
+ <xsd:element name="temporal" type="orm:temporal"
minOccurs="0"/>
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string"
use="required"/>
+ <xsd:attribute name="access" type="orm:access-type"/>
+ </xsd:complexType>
+</xsd:schema>
\ No newline at end of file
Modified: core/trunk/distribution/pom.xml
===================================================================
--- core/trunk/distribution/pom.xml 2010-07-08 17:32:44 UTC (rev 19920)
+++ core/trunk/distribution/pom.xml 2010-07-08 23:41:23 UTC (rev 19921)
@@ -57,7 +57,6 @@
<source><![CDATA[
def sourcePathName = 'javadocSourcePath'
sourcePath = ant.path( id:sourcePathName ) {
- ant.pathElement( path:
"${pom.basedir}/../annotations/src/main/java" )
ant.pathElement( path:
"${pom.basedir}/../cache-ehcache/src/main/java" )
ant.pathElement( path:
"${pom.basedir}/../cache-infinispan/src/main/java" )
ant.pathElement( path:
"${pom.basedir}/../cache-jbosscache/src/main/java" )
@@ -202,11 +201,6 @@
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
- <artifactId>hibernate-jmx</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>${project.version}</version>
</dependency>
@@ -242,11 +236,6 @@
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
- <artifactId>hibernate-annotations</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${project.version}</version>
</dependency>
Modified: core/trunk/entitymanager/pom.xml
===================================================================
--- core/trunk/entitymanager/pom.xml 2010-07-08 17:32:44 UTC (rev 19920)
+++ core/trunk/entitymanager/pom.xml 2010-07-08 23:41:23 UTC (rev 19921)
@@ -24,11 +24,6 @@
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>hibernate-annotations</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
</dependency>
Modified: core/trunk/envers/pom.xml
===================================================================
--- core/trunk/envers/pom.xml 2010-07-08 17:32:44 UTC (rev 19920)
+++ core/trunk/envers/pom.xml 2010-07-08 23:41:23 UTC (rev 19921)
@@ -78,10 +78,6 @@
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
- <artifactId>hibernate-annotations</artifactId>
- </dependency>
- <dependency>
- <groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency>
<dependency>