HHH-18815 @Generated should not imply @Immutable
Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
parent
51254568df
commit
5fca1206b2
|
@ -34,6 +34,11 @@ public class Assigned implements Generator {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean allowMutation() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EnumSet<EventType> getEventTypes() {
|
public EnumSet<EventType> getEventTypes() {
|
||||||
return EventTypeSets.NONE;
|
return EventTypeSets.NONE;
|
||||||
|
|
|
@ -70,16 +70,7 @@ class CompositeGeneratorBuilder {
|
||||||
return createCompositeOnExecutionGenerator();
|
return createCompositeOnExecutionGenerator();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return new Generator() {
|
return DummyGenerator.INSTANCE;
|
||||||
@Override
|
|
||||||
public EnumSet<EventType> getEventTypes() {
|
|
||||||
return NONE;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public boolean generatedOnExecution() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,6 +80,8 @@ class CompositeGeneratorBuilder {
|
||||||
// the base-line values for the aggregated OnExecutionGenerator we will build here.
|
// the base-line values for the aggregated OnExecutionGenerator we will build here.
|
||||||
final EnumSet<EventType> eventTypes = EnumSet.noneOf(EventType.class);
|
final EnumSet<EventType> eventTypes = EnumSet.noneOf(EventType.class);
|
||||||
boolean referenceColumns = false;
|
boolean referenceColumns = false;
|
||||||
|
boolean writable = false;
|
||||||
|
boolean mutable = false;
|
||||||
final String[] columnValues = new String[composite.getColumnSpan()];
|
final String[] columnValues = new String[composite.getColumnSpan()];
|
||||||
|
|
||||||
// start building the aggregate values
|
// start building the aggregate values
|
||||||
|
@ -120,31 +113,16 @@ class CompositeGeneratorBuilder {
|
||||||
columnIndex += span;
|
columnIndex += span;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ( generator.writePropertyValue() ) {
|
||||||
|
writable = true;
|
||||||
|
}
|
||||||
|
if ( generator.allowMutation() ) {
|
||||||
|
mutable = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
final boolean referenceColumnsInSql = referenceColumns;
|
|
||||||
|
|
||||||
// then use the aggregated values to build an OnExecutionGenerator
|
// then use the aggregated values to build an OnExecutionGenerator
|
||||||
return new OnExecutionGenerator() {
|
return new CompositeOnExecutionGenerator( eventTypes, referenceColumns, columnValues, writable, mutable );
|
||||||
@Override
|
|
||||||
public EnumSet<EventType> getEventTypes() {
|
|
||||||
return eventTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean referenceColumnsInSql(Dialect dialect) {
|
|
||||||
return referenceColumnsInSql;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getReferencedColumnValues(Dialect dialect) {
|
|
||||||
return columnValues;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean writePropertyValue() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BeforeExecutionGenerator createCompositeBeforeExecutionGenerator() {
|
private BeforeExecutionGenerator createCompositeBeforeExecutionGenerator() {
|
||||||
|
@ -157,45 +135,98 @@ class CompositeGeneratorBuilder {
|
||||||
eventTypes.addAll( generator.getEventTypes() );
|
eventTypes.addAll( generator.getEventTypes() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new BeforeExecutionGenerator() {
|
return new CompositeBeforeExecutionGenerator( entityName, generators, mappingProperty, properties, eventTypes );
|
||||||
@Override
|
}
|
||||||
public Object generate(SharedSessionContractImplementor session, Object owner, Object currentValue, EventType eventType) {
|
|
||||||
final EntityPersister persister = session.getEntityPersister( entityName, owner );
|
|
||||||
final int index = persister.getPropertyIndex( mappingProperty.getName() );
|
|
||||||
final EmbeddableMappingType descriptor =
|
|
||||||
persister.getAttributeMapping(index).asEmbeddedAttributeMapping()
|
|
||||||
.getEmbeddableTypeDescriptor();
|
|
||||||
final int size = properties.size();
|
|
||||||
if ( currentValue == null ) {
|
|
||||||
final Object[] generatedValues = new Object[size];
|
|
||||||
for ( int i = 0; i < size; i++ ) {
|
|
||||||
final Generator generator = generators.get(i);
|
|
||||||
if ( generator != null ) {
|
|
||||||
generatedValues[i] = ((BeforeExecutionGenerator) generator)
|
|
||||||
.generate( session, owner, null, eventType );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return descriptor.getRepresentationStrategy().getInstantiator()
|
|
||||||
.instantiate( () -> generatedValues, session.getFactory() );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for ( int i = 0; i < size; i++ ) {
|
|
||||||
final Generator generator = generators.get(i);
|
|
||||||
if ( generator != null ) {
|
|
||||||
final Object value = descriptor.getValue( currentValue, i );
|
|
||||||
final Object generatedValue = ((BeforeExecutionGenerator) generator)
|
|
||||||
.generate( session, owner, value, eventType );
|
|
||||||
descriptor.setValue( currentValue, i, generatedValue );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return currentValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
private record CompositeOnExecutionGenerator(
|
||||||
public EnumSet<EventType> getEventTypes() {
|
EnumSet<EventType> eventTypes,
|
||||||
return eventTypes;
|
boolean referenceColumnsInSql,
|
||||||
|
String[] columnValues,
|
||||||
|
boolean writePropertyValue,
|
||||||
|
boolean allowMutation)
|
||||||
|
implements OnExecutionGenerator {
|
||||||
|
@Override
|
||||||
|
public boolean referenceColumnsInSql(Dialect dialect) {
|
||||||
|
return referenceColumnsInSql;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String[] getReferencedColumnValues(Dialect dialect) {
|
||||||
|
return columnValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<EventType> getEventTypes() {
|
||||||
|
return eventTypes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private record CompositeBeforeExecutionGenerator(
|
||||||
|
String entityName,
|
||||||
|
List<Generator> generators,
|
||||||
|
Property mappingProperty,
|
||||||
|
List<Property> properties,
|
||||||
|
EnumSet<EventType> eventTypes)
|
||||||
|
implements BeforeExecutionGenerator {
|
||||||
|
@Override
|
||||||
|
public EnumSet<EventType> getEventTypes() {
|
||||||
|
return eventTypes;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Object generate(SharedSessionContractImplementor session, Object owner, Object currentValue, EventType eventType) {
|
||||||
|
final EntityPersister persister = session.getEntityPersister( entityName, owner );
|
||||||
|
final int index = persister.getPropertyIndex( mappingProperty.getName() );
|
||||||
|
final EmbeddableMappingType descriptor =
|
||||||
|
persister.getAttributeMapping( index ).asEmbeddedAttributeMapping()
|
||||||
|
.getEmbeddableTypeDescriptor();
|
||||||
|
final int size = properties.size();
|
||||||
|
if ( currentValue == null ) {
|
||||||
|
final Object[] generatedValues = new Object[size];
|
||||||
|
for ( int i = 0; i < size; i++ ) {
|
||||||
|
final Generator generator = generators.get( i );
|
||||||
|
if ( generator != null ) {
|
||||||
|
generatedValues[i] = ((BeforeExecutionGenerator) generator)
|
||||||
|
.generate( session, owner, null, eventType );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return descriptor.getRepresentationStrategy().getInstantiator()
|
||||||
|
.instantiate( () -> generatedValues, session.getFactory() );
|
||||||
}
|
}
|
||||||
};
|
else {
|
||||||
|
for ( int i = 0; i < size; i++ ) {
|
||||||
|
final Generator generator = generators.get( i );
|
||||||
|
if ( generator != null ) {
|
||||||
|
final Object value = descriptor.getValue( currentValue, i );
|
||||||
|
final Object generatedValue = ((BeforeExecutionGenerator) generator)
|
||||||
|
.generate( session, owner, value, eventType );
|
||||||
|
descriptor.setValue( currentValue, i, generatedValue );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return currentValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private record DummyGenerator() implements Generator {
|
||||||
|
private static final Generator INSTANCE = new DummyGenerator();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumSet<EventType> getEventTypes() {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean generatedOnExecution() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean allowMutation() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean allowAssignedIdentifiers() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -235,9 +235,9 @@ public class EntityMetamodel implements Serializable {
|
||||||
boolean foundUpdateableNaturalIdProperty = false;
|
boolean foundUpdateableNaturalIdProperty = false;
|
||||||
BeforeExecutionGenerator tempVersionGenerator = null;
|
BeforeExecutionGenerator tempVersionGenerator = null;
|
||||||
|
|
||||||
List<Property> props = persistentClass.getPropertyClosure();
|
final List<Property> props = persistentClass.getPropertyClosure();
|
||||||
for ( int i=0; i<props.size(); i++ ) {
|
for ( int i=0; i<props.size(); i++ ) {
|
||||||
Property property = props.get(i);
|
final Property property = props.get(i);
|
||||||
final NonIdentifierAttribute attribute;
|
final NonIdentifierAttribute attribute;
|
||||||
if ( property == persistentClass.getVersion() ) {
|
if ( property == persistentClass.getVersion() ) {
|
||||||
tempVersionProperty = i;
|
tempVersionProperty = i;
|
||||||
|
@ -310,9 +310,11 @@ public class EntityMetamodel implements Serializable {
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
// generated value strategies ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// generated value strategies ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
final Generator generator = buildGenerator( name, property, creationContext );
|
final Generator generator = buildGenerator( name, property, creationContext );
|
||||||
if ( generator != null ) {
|
if ( generator != null ) {
|
||||||
if ( i == tempVersionProperty && !generator.generatedOnExecution() ) {
|
final boolean generatedOnExecution = generator.generatedOnExecution();
|
||||||
|
if ( i == tempVersionProperty && !generatedOnExecution ) {
|
||||||
// when we have an in-memory generator for the version, we
|
// when we have an in-memory generator for the version, we
|
||||||
// want to plug it in to the older infrastructure specific
|
// want to plug it in to the older infrastructure specific
|
||||||
// to version generation, instead of treating it like a
|
// to version generation, instead of treating it like a
|
||||||
|
@ -321,33 +323,33 @@ public class EntityMetamodel implements Serializable {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
generators[i] = generator;
|
generators[i] = generator;
|
||||||
if ( !generator.allowMutation() ) {
|
final boolean allowMutation = generator.allowMutation();
|
||||||
propertyInsertability[i] = false;
|
if ( !allowMutation ) {
|
||||||
propertyUpdateability[i] = false;
|
propertyCheckability[i] = false;
|
||||||
}
|
}
|
||||||
if ( generator.generatesOnInsert() ) {
|
if ( generator.generatesOnInsert() ) {
|
||||||
propertyInsertability[i] = !generatedWithNoParameter( generator );
|
if ( generatedOnExecution ) {
|
||||||
if ( generator.generatedOnExecution() ) {
|
propertyInsertability[i] = writePropertyValue( (OnExecutionGenerator) generator );
|
||||||
foundPostInsertGeneratedValues = true;
|
|
||||||
if ( generator instanceof BeforeExecutionGenerator ) {
|
|
||||||
foundPreInsertGeneratedValues = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
foundPreInsertGeneratedValues = true;
|
|
||||||
}
|
}
|
||||||
|
foundPostInsertGeneratedValues = foundPostInsertGeneratedValues
|
||||||
|
|| generator instanceof OnExecutionGenerator;
|
||||||
|
foundPreInsertGeneratedValues = foundPreInsertGeneratedValues
|
||||||
|
|| generator instanceof BeforeExecutionGenerator;
|
||||||
|
}
|
||||||
|
else if ( !allowMutation ) {
|
||||||
|
propertyInsertability[i] = false;
|
||||||
}
|
}
|
||||||
if ( generator.generatesOnUpdate() ) {
|
if ( generator.generatesOnUpdate() ) {
|
||||||
propertyUpdateability[i] = !generatedWithNoParameter( generator );
|
if ( generatedOnExecution ) {
|
||||||
if ( generator.generatedOnExecution() ) {
|
propertyUpdateability[i] = writePropertyValue( (OnExecutionGenerator) generator );
|
||||||
foundPostUpdateGeneratedValues = true;
|
|
||||||
if ( generator instanceof BeforeExecutionGenerator ) {
|
|
||||||
foundPreUpdateGeneratedValues = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
foundPreUpdateGeneratedValues = true;
|
|
||||||
}
|
}
|
||||||
|
foundPostUpdateGeneratedValues = foundPostUpdateGeneratedValues
|
||||||
|
|| generator instanceof OnExecutionGenerator;
|
||||||
|
foundPreUpdateGeneratedValues = foundPreUpdateGeneratedValues
|
||||||
|
|| generator instanceof BeforeExecutionGenerator;
|
||||||
|
}
|
||||||
|
else if ( !allowMutation ) {
|
||||||
|
propertyUpdateability[i] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -472,6 +474,15 @@ public class EntityMetamodel implements Serializable {
|
||||||
// entityNameByInheritanceClassMap = toSmallMap( entityNameByInheritanceClassMapLocal );
|
// entityNameByInheritanceClassMap = toSmallMap( entityNameByInheritanceClassMapLocal );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean writePropertyValue(OnExecutionGenerator generator) {
|
||||||
|
final boolean writePropertyValue = generator.writePropertyValue();
|
||||||
|
// TODO: move this validation somewhere else!
|
||||||
|
// if ( !writePropertyValue && generator instanceof BeforeExecutionGenerator ) {
|
||||||
|
// throw new HibernateException( "BeforeExecutionGenerator returned false from OnExecutionGenerator.writePropertyValue()" );
|
||||||
|
// }
|
||||||
|
return writePropertyValue;
|
||||||
|
}
|
||||||
|
|
||||||
private Generator buildIdGenerator(PersistentClass persistentClass, RuntimeModelCreationContext creationContext) {
|
private Generator buildIdGenerator(PersistentClass persistentClass, RuntimeModelCreationContext creationContext) {
|
||||||
final Generator existing = creationContext.getGenerators().get( rootName );
|
final Generator existing = creationContext.getGenerators().get( rootName );
|
||||||
if ( existing != null ) {
|
if ( existing != null ) {
|
||||||
|
@ -513,11 +524,6 @@ public class EntityMetamodel implements Serializable {
|
||||||
return getName() + "." + property.getName();
|
return getName() + "." + property.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean generatedWithNoParameter(Generator generator) {
|
|
||||||
return generator.generatedOnExecution()
|
|
||||||
&& !((OnExecutionGenerator) generator).writePropertyValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Generator buildGenerator(
|
private static Generator buildGenerator(
|
||||||
final String entityName,
|
final String entityName,
|
||||||
final Property mappingProperty,
|
final Property mappingProperty,
|
||||||
|
|
|
@ -11,6 +11,7 @@ import jakarta.persistence.Id;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import org.hibernate.annotations.DialectOverride;
|
import org.hibernate.annotations.DialectOverride;
|
||||||
import org.hibernate.annotations.Generated;
|
import org.hibernate.annotations.Generated;
|
||||||
|
import org.hibernate.annotations.Immutable;
|
||||||
import org.hibernate.annotations.SQLInsert;
|
import org.hibernate.annotations.SQLInsert;
|
||||||
import org.hibernate.annotations.SQLUpdate;
|
import org.hibernate.annotations.SQLUpdate;
|
||||||
import org.hibernate.dialect.H2Dialect;
|
import org.hibernate.dialect.H2Dialect;
|
||||||
|
@ -82,7 +83,7 @@ public class CustomSqlOverrideTest {
|
||||||
static class Custom {
|
static class Custom {
|
||||||
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
|
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
Long id;
|
Long id;
|
||||||
@Generated
|
@Generated @Immutable
|
||||||
String uid;
|
String uid;
|
||||||
String whatever;
|
String whatever;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,13 +44,13 @@ public class DefaultTest {
|
||||||
assertEquals( unitPrice, entity.unitPrice );
|
assertEquals( unitPrice, entity.unitPrice );
|
||||||
assertEquals( 5, entity.quantity );
|
assertEquals( 5, entity.quantity );
|
||||||
assertEquals( "new", entity.status );
|
assertEquals( "new", entity.status );
|
||||||
entity.status = "old"; //should be ignored when fetch=true
|
entity.status = "old";
|
||||||
} );
|
} );
|
||||||
scope.inTransaction( session -> {
|
scope.inTransaction( session -> {
|
||||||
OrderLine entity = session.createQuery("from WithDefault", OrderLine.class ).getSingleResult();
|
OrderLine entity = session.createQuery("from WithDefault", OrderLine.class ).getSingleResult();
|
||||||
assertEquals( unitPrice, entity.unitPrice );
|
assertEquals( unitPrice, entity.unitPrice );
|
||||||
assertEquals( 5, entity.quantity );
|
assertEquals( 5, entity.quantity );
|
||||||
assertEquals( "new", entity.status );
|
assertEquals( "old", entity.status );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
* Copyright Red Hat Inc. and Hibernate Authors
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.mapping.generated.sqldefault;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import org.hibernate.annotations.ColumnDefault;
|
||||||
|
import org.hibernate.annotations.Generated;
|
||||||
|
import org.hibernate.annotations.Immutable;
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Gavin King
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("JUnitMalformedDeclaration")
|
||||||
|
@DomainModel(annotatedClasses = ImmutableDefaultTest.OrderLine.class)
|
||||||
|
@SessionFactory
|
||||||
|
public class ImmutableDefaultTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test(SessionFactoryScope scope) {
|
||||||
|
BigDecimal unitPrice = new BigDecimal("12.99");
|
||||||
|
scope.inTransaction( session -> {
|
||||||
|
OrderLine entity = new OrderLine( unitPrice, 5 );
|
||||||
|
session.persist(entity);
|
||||||
|
session.flush();
|
||||||
|
assertEquals( "new", entity.status );
|
||||||
|
assertEquals( unitPrice, entity.unitPrice );
|
||||||
|
assertEquals( 5, entity.quantity );
|
||||||
|
} );
|
||||||
|
scope.inTransaction( session -> {
|
||||||
|
OrderLine entity = session.createQuery("from WithDefault", OrderLine.class ).getSingleResult();
|
||||||
|
assertEquals( unitPrice, entity.unitPrice );
|
||||||
|
assertEquals( 5, entity.quantity );
|
||||||
|
assertEquals( "new", entity.status );
|
||||||
|
entity.status = "old"; //should be ignored due to @Immutable
|
||||||
|
} );
|
||||||
|
scope.inTransaction( session -> {
|
||||||
|
OrderLine entity = session.createQuery("from WithDefault", OrderLine.class ).getSingleResult();
|
||||||
|
assertEquals( unitPrice, entity.unitPrice );
|
||||||
|
assertEquals( 5, entity.quantity );
|
||||||
|
assertEquals( "new", entity.status );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void dropTestData(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction( session -> session.createQuery( "delete WithDefault" ).executeUpdate() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name="WithDefault")
|
||||||
|
public static class OrderLine {
|
||||||
|
@Id
|
||||||
|
private BigDecimal unitPrice;
|
||||||
|
@Id @ColumnDefault(value = "1")
|
||||||
|
private int quantity;
|
||||||
|
@Generated @Immutable
|
||||||
|
@ColumnDefault(value = "'new'")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
public OrderLine() {}
|
||||||
|
public OrderLine(BigDecimal unitPrice, int quantity) {
|
||||||
|
this.unitPrice = unitPrice;
|
||||||
|
this.quantity = quantity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -52,7 +52,7 @@ public class OverriddenDefaultTest {
|
||||||
OrderLine entity = session.createQuery("from WithDefault", OrderLine.class ).getSingleResult();
|
OrderLine entity = session.createQuery("from WithDefault", OrderLine.class ).getSingleResult();
|
||||||
assertEquals( unitPrice, entity.unitPrice );
|
assertEquals( unitPrice, entity.unitPrice );
|
||||||
assertEquals( 5, entity.quantity );
|
assertEquals( 5, entity.quantity );
|
||||||
assertEquals( getDefault(scope), entity.status );
|
assertEquals( "old", entity.status );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue