HHH-2907 Retrofitting @Generated, making it a generator annotation type
This commit is contained in:
parent
cc30269b84
commit
fd57a751b4
|
@ -28,14 +28,18 @@ import java.lang.annotation.Retention;
|
|||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.hibernate.tuple.GeneratedValueGeneration;
|
||||
|
||||
/**
|
||||
* The annotated property is generated by the database.
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@ValueGenerationType( generatedBy = GeneratedValueGeneration.class )
|
||||
@Target({ElementType.FIELD, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Generated {
|
||||
|
||||
/**
|
||||
* The enum value representing when the value is generated.
|
||||
*/
|
||||
|
|
|
@ -34,7 +34,6 @@ import org.dom4j.Attribute;
|
|||
import org.dom4j.Document;
|
||||
import org.dom4j.Element;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.CacheMode;
|
||||
import org.hibernate.EntityMode;
|
||||
import org.hibernate.FetchMode;
|
||||
|
@ -96,6 +95,7 @@ import org.hibernate.mapping.TypeDef;
|
|||
import org.hibernate.mapping.UnionSubclass;
|
||||
import org.hibernate.mapping.UniqueKey;
|
||||
import org.hibernate.mapping.Value;
|
||||
import org.hibernate.tuple.GeneratedValueGeneration;
|
||||
import org.hibernate.tuple.GenerationTiming;
|
||||
import org.hibernate.tuple.ValueGeneration;
|
||||
import org.hibernate.tuple.ValueGenerator;
|
||||
|
@ -1307,7 +1307,7 @@ public final class HbmBinder {
|
|||
if ( generationTiming == GenerationTiming.ALWAYS || generationTiming == GenerationTiming.INSERT ) {
|
||||
// we had generation specified...
|
||||
// HBM only supports "database generated values"
|
||||
property.setValueGenerationStrategy( new HbmDefinedValueGeneration( generationTiming ) );
|
||||
property.setValueGenerationStrategy( new GeneratedValueGeneration( generationTiming ) );
|
||||
|
||||
// generated properties can *never* be insertable...
|
||||
if ( property.isInsertable() ) {
|
||||
|
@ -1370,37 +1370,6 @@ public final class HbmBinder {
|
|||
|
||||
}
|
||||
|
||||
private static class HbmDefinedValueGeneration implements ValueGeneration {
|
||||
private final GenerationTiming timing;
|
||||
|
||||
private HbmDefinedValueGeneration(GenerationTiming timing) {
|
||||
this.timing = timing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenerationTiming getGenerationTiming() {
|
||||
return timing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueGenerator getValueGenerator() {
|
||||
// database generated values do not have a value generator
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean referenceColumnInSql() {
|
||||
// historically these columns are not referenced in the SQL
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDatabaseGeneratedReferencedColumnValue() {
|
||||
// the column is not referenced in the sql.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static String columns(Value val) {
|
||||
StringBuilder columns = new StringBuilder();
|
||||
Iterator iter = val.getColumnIterator();
|
||||
|
|
|
@ -33,7 +33,6 @@ import javax.persistence.Lob;
|
|||
import org.hibernate.AnnotationException;
|
||||
import org.hibernate.HibernateException;
|
||||
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;
|
||||
|
@ -333,50 +332,22 @@ public class PropertyBinder {
|
|||
}
|
||||
|
||||
private ValueGeneration determineValueGenerationStrategy(XProperty property) {
|
||||
ValueGeneration annotationValueGeneration = getValueGenerationFromAnnotations( property );
|
||||
ValueGeneration legacyValueGeneration = getLegacyValueGeneration( property );
|
||||
ValueGeneration valueGeneration = getValueGenerationFromAnnotations( property );
|
||||
|
||||
if ( annotationValueGeneration == null && legacyValueGeneration == null ) {
|
||||
if ( valueGeneration == null ) {
|
||||
return NoValueGeneration.INSTANCE;
|
||||
}
|
||||
else if ( annotationValueGeneration != null && legacyValueGeneration != null ) {
|
||||
throw new AnnotationException(
|
||||
"@Generated and a generator annotation must not be specified at the same time:" + StringHelper.qualify(
|
||||
holder.getPath(),
|
||||
name
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
final GenerationTiming when = annotationValueGeneration != null ?
|
||||
annotationValueGeneration.getGenerationTiming() :
|
||||
legacyValueGeneration.getGenerationTiming();
|
||||
final GenerationTiming when = valueGeneration.getGenerationTiming();
|
||||
|
||||
if ( property.isAnnotationPresent( javax.persistence.Version.class ) && when == GenerationTiming.INSERT ) {
|
||||
throw new AnnotationException(
|
||||
"@Generated(INSERT) on a @Version property not allowed, use ALWAYS (or NEVER): "
|
||||
+ StringHelper.qualify( holder.getPath(), name )
|
||||
);
|
||||
}
|
||||
|
||||
if ( legacyValueGeneration != null ) {
|
||||
if ( valueGeneration.getValueGenerator() == null ) {
|
||||
insertable = false;
|
||||
if ( when == GenerationTiming.ALWAYS ) {
|
||||
updatable = false;
|
||||
}
|
||||
}
|
||||
|
||||
return annotationValueGeneration != null ? annotationValueGeneration : legacyValueGeneration;
|
||||
}
|
||||
|
||||
private ValueGeneration getLegacyValueGeneration(XProperty property) {
|
||||
Generated generatedAnnotation = property.getAnnotation( Generated.class );
|
||||
|
||||
if ( generatedAnnotation != null && generatedAnnotation.value() != null && generatedAnnotation.value() != GenerationTime.NEVER ) {
|
||||
return new LegacyValueGeneration( generatedAnnotation.value().getEquivalent() );
|
||||
}
|
||||
|
||||
return null;
|
||||
return valueGeneration;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -421,9 +392,21 @@ public class PropertyBinder {
|
|||
}
|
||||
|
||||
Class<? extends AnnotationValueGeneration<?>> generationType = generatorAnnotation.generatedBy();
|
||||
return instantiateAndInitializeValueGeneration(
|
||||
AnnotationValueGeneration<A> valueGeneration = instantiateAndInitializeValueGeneration(
|
||||
annotation, generationType, property
|
||||
);
|
||||
|
||||
if ( annotation.annotationType() == Generated.class &&
|
||||
property.isAnnotationPresent( javax.persistence.Version.class ) &&
|
||||
valueGeneration.getGenerationTiming() == GenerationTiming.INSERT ) {
|
||||
|
||||
throw new AnnotationException(
|
||||
"@Generated(INSERT) on a @Version property not allowed, use ALWAYS (or NEVER): "
|
||||
+ StringHelper.qualify( holder.getPath(), name )
|
||||
);
|
||||
}
|
||||
|
||||
return valueGeneration;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -470,7 +453,7 @@ public class PropertyBinder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ValueGenerator getValueGenerator() {
|
||||
public ValueGenerator<?> getValueGenerator() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -485,40 +468,6 @@ public class PropertyBinder {
|
|||
}
|
||||
}
|
||||
|
||||
private static class LegacyValueGeneration implements ValueGeneration {
|
||||
private final GenerationTiming timing;
|
||||
|
||||
private LegacyValueGeneration(GenerationTiming timing) {
|
||||
this.timing = timing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenerationTiming getGenerationTiming() {
|
||||
return timing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueGenerator getValueGenerator() {
|
||||
// database generated values do not have a value generator
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean referenceColumnInSql() {
|
||||
// historically these columns are not referenced in the SQL
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDatabaseGeneratedReferencedColumnValue() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isCollection(Value value) {
|
||||
return Collection.class.isInstance( value );
|
||||
}
|
||||
|
||||
private boolean isToOneValue(Value value) {
|
||||
return ToOne.class.isInstance( value );
|
||||
}
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2013, 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.tuple;
|
||||
|
||||
import org.hibernate.annotations.Generated;
|
||||
|
||||
/**
|
||||
* A {@link AnnotationValueGeneration} which marks a property as generated in the database.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Gunnar Morling
|
||||
*/
|
||||
public class GeneratedValueGeneration implements AnnotationValueGeneration<Generated> {
|
||||
|
||||
private GenerationTiming timing;
|
||||
|
||||
public GeneratedValueGeneration() {
|
||||
}
|
||||
|
||||
public GeneratedValueGeneration(GenerationTiming timing) {
|
||||
this.timing = timing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(Generated annotation, Class<?> propertyType) {
|
||||
this.timing = annotation.value().getEquivalent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenerationTiming getGenerationTiming() {
|
||||
return timing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueGenerator<?> getValueGenerator() {
|
||||
// database generated values do not have a value generator
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean referenceColumnInSql() {
|
||||
// historically these columns are not referenced in the SQL
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDatabaseGeneratedReferencedColumnValue() {
|
||||
return null;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue