1
// $Id: PropertyFactory.java 10119 2006-07-14 00:09:19Z steve.ebersole@jboss.com $
2
package org.hibernate.tuple;
4
import java.lang.reflect.Constructor;
6
import org.hibernate.EntityMode;
7
import org.hibernate.mapping.PropertyGeneration;
8
import org.hibernate.engine.IdentifierValue;
9
import org.hibernate.engine.UnsavedValueFactory;
10
import org.hibernate.engine.VersionValue;
11
import org.hibernate.id.IdentifierGenerator;
12
import org.hibernate.mapping.KeyValue;
13
import org.hibernate.mapping.PersistentClass;
14
import org.hibernate.mapping.Property;
15
import org.hibernate.property.Getter;
16
import org.hibernate.property.PropertyAccessor;
17
import org.hibernate.property.PropertyAccessorFactory;
18
import org.hibernate.type.AssociationType;
19
import org.hibernate.type.Type;
20
import org.hibernate.type.VersionType;
21
import org.hibernate.util.ReflectHelper;
24
* Responsible for generation of runtime metamodel {@link Property} representations.
25
* Makes distinction between identifier, version, and other (standard) properties.
27
* @author Steve Ebersole
29
public class PropertyFactory {
32
* Generates an IdentifierProperty representation of the for a given entity mapping.
34
* @param mappedEntity The mapping definition of the entity.
35
* @param generator The identifier value generator to use for this identifier.
36
* @return The appropriate IdentifierProperty definition.
38
public static IdentifierProperty buildIdentifierProperty(PersistentClass mappedEntity, IdentifierGenerator generator) {
40
String mappedUnsavedValue = mappedEntity.getIdentifier().getNullValue();
41
Type type = mappedEntity.getIdentifier().getType();
42
Property property = mappedEntity.getIdentifierProperty();
44
IdentifierValue unsavedValue = UnsavedValueFactory.getUnsavedIdentifierValue(
46
getGetter( property ),
48
getConstructor(mappedEntity)
51
if ( property == null ) {
52
// this is a virtual id property...
53
return new IdentifierProperty(
55
mappedEntity.hasEmbeddedIdentifier(),
56
mappedEntity.hasIdentifierMapper(),
62
return new IdentifierProperty(
64
property.getNodeName(),
66
mappedEntity.hasEmbeddedIdentifier(),
74
* Generates a VersionProperty representation for an entity mapping given its
75
* version mapping Property.
77
* @param property The version mapping Property.
78
* @param lazyAvailable Is property lazy loading currently available.
79
* @return The appropriate VersionProperty definition.
81
public static VersionProperty buildVersionProperty(Property property, boolean lazyAvailable) {
82
String mappedUnsavedValue = ( (KeyValue) property.getValue() ).getNullValue();
84
VersionValue unsavedValue = UnsavedValueFactory.getUnsavedVersionValue(
86
getGetter( property ),
87
(VersionType) property.getType(),
88
getConstructor( property.getPersistentClass() )
91
boolean lazy = lazyAvailable && property.isLazy();
93
return new VersionProperty(
95
property.getNodeName(),
96
property.getValue().getType(),
98
property.isInsertable(),
99
property.isUpdateable(),
100
property.getGeneration() == PropertyGeneration.INSERT || property.getGeneration() == PropertyGeneration.ALWAYS,
101
property.getGeneration() == PropertyGeneration.ALWAYS,
102
property.isOptional(),
103
property.isUpdateable() && !lazy,
104
property.isOptimisticLocked(),
105
property.getCascadeStyle(),
111
* Generate a "standard" (i.e., non-identifier and non-version) based on the given
114
* @param property The mapped property.
115
* @param lazyAvailable Is property lazy loading currently available.
116
* @return The appropriate StandardProperty definition.
118
public static StandardProperty buildStandardProperty(Property property, boolean lazyAvailable) {
120
final Type type = property.getValue().getType();
122
// we need to dirty check collections, since they can cause an owner
123
// version number increment
125
// we need to dirty check many-to-ones with not-found="ignore" in order
126
// to update the cache (not the database), since in this case a null
127
// entity reference can lose information
129
boolean alwaysDirtyCheck = type.isAssociationType() &&
130
( (AssociationType) type ).isAlwaysDirtyChecked();
132
return new StandardProperty(
134
property.getNodeName(),
136
lazyAvailable && property.isLazy(),
137
property.isInsertable(),
138
property.isUpdateable(),
139
property.getGeneration() == PropertyGeneration.INSERT || property.getGeneration() == PropertyGeneration.ALWAYS,
140
property.getGeneration() == PropertyGeneration.ALWAYS,
141
property.isOptional(),
142
alwaysDirtyCheck || property.isUpdateable(),
143
property.isOptimisticLocked(),
144
property.getCascadeStyle(),
145
property.getValue().getFetchMode()
149
private static Constructor getConstructor(PersistentClass persistentClass) {
150
if ( persistentClass == null || !persistentClass.hasPojoRepresentation() ) {
155
return ReflectHelper.getDefaultConstructor( persistentClass.getMappedClass() );
157
catch( Throwable t ) {
162
private static Getter getGetter(Property mappingProperty) {
163
if ( mappingProperty == null || !mappingProperty.getPersistentClass().hasPojoRepresentation() ) {
167
PropertyAccessor pa = PropertyAccessorFactory.getPropertyAccessor( mappingProperty, EntityMode.POJO );
168
return pa.getGetter( mappingProperty.getPersistentClass().getMappedClass(), mappingProperty.getName() );