diff --git a/annotations/src/main/java/org/hibernate/annotations/TypeDef.java b/annotations/src/main/java/org/hibernate/annotations/TypeDef.java index 0806f8553e..dbb7fcd75c 100644 --- a/annotations/src/main/java/org/hibernate/annotations/TypeDef.java +++ b/annotations/src/main/java/org/hibernate/annotations/TypeDef.java @@ -1,7 +1,7 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * 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. @@ -37,9 +37,9 @@ import java.lang.annotation.Target; @Target({TYPE, PACKAGE}) @Retention(RUNTIME) public @interface TypeDef { - String name(); - - Class typeClass(); - + String name() default ""; + Class typeClass(); + Class defaultForType() default void.class; + Parameter[] parameters() default {}; } diff --git a/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java b/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java index ff16906b75..18ed9b3b07 100644 --- a/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java +++ b/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java @@ -104,7 +104,6 @@ import org.hibernate.annotations.Index; import org.hibernate.annotations.LazyToOne; import org.hibernate.annotations.LazyToOneOption; import org.hibernate.annotations.ManyToAny; -import org.hibernate.annotations.MapKeyManyToMany; import org.hibernate.annotations.NaturalId; import org.hibernate.annotations.NotFound; import org.hibernate.annotations.NotFoundAction; @@ -137,7 +136,6 @@ import org.hibernate.cfg.annotations.QueryBinder; import org.hibernate.cfg.annotations.SimpleValueBinder; import org.hibernate.cfg.annotations.TableBinder; import org.hibernate.cfg.annotations.MapKeyColumnDelegator; -import org.hibernate.cfg.annotations.CustomizableColumns; import org.hibernate.cfg.annotations.MapKeyJoinColumnDelegator; import org.hibernate.engine.FilterDefinition; import org.hibernate.engine.Versioning; @@ -1005,10 +1003,24 @@ public final class AnnotationBinder { for (Parameter param : defAnn.parameters()) { params.setProperty( param.name(), param.value() ); } - log.info( "Binding type definition: {}", defAnn.name() ); - mappings.addTypeDef( defAnn.name(), defAnn.typeClass().getName(), params ); + + if (BinderHelper.isDefault(defAnn.name()) && defAnn.defaultForType().equals(void.class)) { + throw new AnnotationException("Both name and defaultForType attributes cannot be set in a TypeDef"); + } + if (!BinderHelper.isDefault(defAnn.name())) { + log.info( "Binding type definition: {}", defAnn.name() ); + mappings.addTypeDef( defAnn.name(), defAnn.typeClass().getName(), params ); + } + else if (!defAnn.defaultForType().equals(void.class)) { + log.info( "Binding type definition: {}", defAnn.defaultForType().getName() ); + mappings.addTypeDef( defAnn.defaultForType().getName(), defAnn.typeClass().getName(), params ); + } + else { + throw new AnnotationException("Either name or defaultForType attribute should be set in a TypeDef"); + } } - + + private static void bindDiscriminatorToPersistentClass( RootClass rootClass, Ejb3DiscriminatorColumn discriminatorColumn, Map secondaryTables, @@ -1365,12 +1377,13 @@ public final class AnnotationBinder { propBinder.setHolder( propertyHolder ); //PropertyHolderBuilder.buildPropertyHolder(rootClass) propBinder.setProperty( property ); propBinder.setReturnedClass( inferredData.getPropertyClass() ); - propBinder.setMappings( mappings ); + Property prop = propBinder.bind(); + propBinder.getSimpleValueBinder().setVersion(true); rootClass.setVersion( prop ); + SimpleValue simpleValue = (SimpleValue) prop.getValue(); - if ( !simpleValue.isTypeSpecified() ) simpleValue.setTypeName( "integer" ); simpleValue.setNullValue( "undefined" ); rootClass.setOptimisticLockMode( Versioning.OPTIMISTIC_LOCK_VERSION ); log.debug( diff --git a/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java b/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java index 84c71f633a..0f96a7f7e2 100644 --- a/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java +++ b/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java @@ -283,7 +283,7 @@ public class AnnotationConfiguration extends Configuration { AnnotationBinder.bindDefaults( createExtendedMappings() ); isDefaultProcessed = true; } - + //process entities if ( precedence == null ) precedence = getProperties().getProperty( ARTEFACT ); if ( precedence == null ) precedence = DEFAULT_PRECEDENCE; @@ -312,8 +312,17 @@ public class AnnotationConfiguration extends Configuration { caches.clear(); try { inSecondPass = true; - processFkSecondPassInOrder(); 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 ( sp instanceof SetSimpleValueTypeSecondPass ) { + sp.doSecondPass( classes ); + iter.remove(); + } + } + processFkSecondPassInOrder(); + iter = secondPasses.iterator(); while ( iter.hasNext() ) { SecondPass sp = (SecondPass) iter.next(); //do the second pass of fk before the others and remove them @@ -1111,6 +1120,11 @@ public class AnnotationConfiguration extends Configuration { defaultNamedGenerators.add( generator.getName() ); } + public boolean isInSecondPass() { + return inSecondPass; + } + + public IdGenerator getGenerator(String name) { return getGenerator( name, null ); } diff --git a/annotations/src/main/java/org/hibernate/cfg/ExtendedMappings.java b/annotations/src/main/java/org/hibernate/cfg/ExtendedMappings.java index 0a6679953d..5ecc6863aa 100644 --- a/annotations/src/main/java/org/hibernate/cfg/ExtendedMappings.java +++ b/annotations/src/main/java/org/hibernate/cfg/ExtendedMappings.java @@ -156,4 +156,7 @@ public interface ExtendedMappings extends Mappings { public void addAnyMetaDef(AnyMetaDef defAnn) throws AnnotationException; public AnyMetaDef getAnyMetaDef(String name); + + public boolean isInSecondPass(); + } \ No newline at end of file diff --git a/annotations/src/main/java/org/hibernate/cfg/SetSimpleValueTypeSecondPass.java b/annotations/src/main/java/org/hibernate/cfg/SetSimpleValueTypeSecondPass.java new file mode 100644 index 0000000000..84a2f5bbf0 --- /dev/null +++ b/annotations/src/main/java/org/hibernate/cfg/SetSimpleValueTypeSecondPass.java @@ -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(); + } + +} diff --git a/annotations/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java b/annotations/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java index f4619b1dd9..599dc8815d 100644 --- a/annotations/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java +++ b/annotations/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java @@ -61,6 +61,8 @@ public class PropertyBinder { private boolean insertable = true; private boolean updatable = true; private String cascade; + private SimpleValueBinder simpleValueBinder; + /* * property can be null * prefer propertyName to property.getName() since some are overloaded @@ -133,15 +135,15 @@ public class PropertyBinder { String containerClassName = holder == null ? null : holder.getClassName(); - SimpleValueBinder value = new SimpleValueBinder(); - value.setMappings( mappings ); - value.setPropertyName( name ); - value.setReturnedClassName( returnedClassName ); - value.setColumns( columns ); - value.setPersistentClassName( containerClassName ); - value.setType( property, returnedClass ); - value.setMappings( mappings ); - SimpleValue propertyValue = value.make(); + 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 ); + SimpleValue propertyValue = simpleValueBinder.make(); setValue( propertyValue ); Property prop = make(); holder.addProperty( prop, columns ); @@ -214,4 +216,9 @@ public class PropertyBinder { public void setReturnedClass(XClass returnedClass) { this.returnedClass = returnedClass; } + + public SimpleValueBinder getSimpleValueBinder() { + return simpleValueBinder; + } + } diff --git a/annotations/src/main/java/org/hibernate/cfg/annotations/SimpleValueBinder.java b/annotations/src/main/java/org/hibernate/cfg/annotations/SimpleValueBinder.java index cc203964d5..da9c50ae56 100644 --- a/annotations/src/main/java/org/hibernate/cfg/annotations/SimpleValueBinder.java +++ b/annotations/src/main/java/org/hibernate/cfg/annotations/SimpleValueBinder.java @@ -42,6 +42,7 @@ import org.hibernate.cfg.BinderHelper; import org.hibernate.cfg.Ejb3Column; import org.hibernate.cfg.ExtendedMappings; import org.hibernate.cfg.NotYetImplementedException; +import org.hibernate.cfg.SetSimpleValueTypeSecondPass; import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.Table; import org.hibernate.type.ByteArrayBlobType; @@ -68,6 +69,16 @@ public class SimpleValueBinder { private Properties typeParameters = new Properties(); private ExtendedMappings mappings; private Table table; + private SimpleValue simpleValue; + private boolean isVersion; + + public boolean isVersion() { + return isVersion; + } + + public void setVersion(boolean isVersion) { + this.isVersion = isVersion; + } public void setPropertyName(String propertyName) { this.propertyName = propertyName; @@ -216,7 +227,7 @@ public class SimpleValueBinder { 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 ) { @@ -238,16 +249,35 @@ public class SimpleValueBinder { } public SimpleValue make() { + validate(); log.debug( "building SimpleValue for {}", propertyName ); if ( table == null ) { table = columns[0].getTable(); } - SimpleValue simpleValue = new SimpleValue( table ); - return fillSimpleValue( simpleValue ); + simpleValue = new SimpleValue( table ); + + for (Ejb3Column column : columns) { + column.linkWithValue( simpleValue ); + } + + boolean isInSecondPass = mappings.isInSecondPass(); + if (!isInSecondPass) { + //Defer this to the second pass + SetSimpleValueTypeSecondPass secondPass = new SetSimpleValueTypeSecondPass(this); + mappings.addSecondPass(secondPass); + } + else { + //We are already in second pass + fillSimpleValue(); + } + return simpleValue; } - public SimpleValue fillSimpleValue(SimpleValue 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 ) { @@ -262,9 +292,10 @@ public class SimpleValueBinder { if ( persistentClassName != null ) { simpleValue.setTypeUsingReflection( persistentClassName, propertyName ); } - for (Ejb3Column column : columns) { - column.linkWithValue( simpleValue ); + + if ( !simpleValue.isTypeSpecified() && isVersion()) { + simpleValue.setTypeName( "integer" ); } - return simpleValue; + } } diff --git a/annotations/src/test/java/org/hibernate/test/annotations/entity/BasicHibernateAnnotationsTest.java b/annotations/src/test/java/org/hibernate/test/annotations/entity/BasicHibernateAnnotationsTest.java index cbaaa30bbf..49bf0a22d3 100644 --- a/annotations/src/test/java/org/hibernate/test/annotations/entity/BasicHibernateAnnotationsTest.java +++ b/annotations/src/test/java/org/hibernate/test/annotations/entity/BasicHibernateAnnotationsTest.java @@ -158,7 +158,7 @@ public class BasicHibernateAnnotationsTest extends TestCase { s.persist(name); tx.commit(); s.close(); - + s = openSession(); tx = s.beginTransaction(); name = (Name) s.get( Name.class, name.getId() ); @@ -341,6 +341,76 @@ public class BasicHibernateAnnotationsTest extends TestCase { tx.commit(); s.close(); } + + + /** + * We persist and retrieve properties of type 'PhoneNumber'. We set this type to delegate to + * the Hibernate UserType 'PhoneNumberType' for persistence and retrieval (with the 'defaultForType' attribute). + * However, we can also use the @TypeDef 'name' attribute and @Type annotation to over-ride this and + * delegate to OverseasPhoneNumberType. + * + */ + public void testTypeDefsUsingNameAndDefaultForType() { + + ContactDetails contactDetails = new ContactDetails(); + contactDetails.setLocalPhoneNumber(new PhoneNumber("999999")); + contactDetails.setOverseasPhoneNumber(new PhoneNumber("111111")); + + Session s = openSession(); + Transaction tx = s.beginTransaction(); + s.persist(contactDetails); + tx.commit(); + s.close(); + + s = openSession(); + tx = s.beginTransaction(); + contactDetails = + (ContactDetails) s.get( ContactDetails.class, contactDetails.getId() ); + assertNotNull( contactDetails ); + assertEquals( "999999", contactDetails.getLocalPhoneNumber().getNumber() ); + assertEquals( "041111111", contactDetails.getOverseasPhoneNumber().getNumber() ); + s.delete(contactDetails); + tx.commit(); + s.close(); + + + + } + + + + /** + * A custom type is used in the base class, but defined in the derived class. + * This would have caused an exception, because the base class is processed + * BEFORE the derived class, and the custom type is not yet defined. However, + * it works now because we are setting the typeName for SimpleValue in the second + * pass. + * + * + * @throws Exception + */ + public void testSetSimpleValueTypeNameInSecondPass() throws Exception { + Peugot derived = new Peugot(); + derived.setName("sharath"); + + Session s; + Transaction tx; + s = openSession(); + tx = s.beginTransaction(); + s.persist(derived); + tx.commit(); + s.close(); + + s = openSession(); + tx = s.beginTransaction(); + derived = (Peugot) s.get( Peugot.class, derived.getId() ); + assertNotNull( derived ); + assertEquals( "SHARATH", derived.getName() ); + s.delete(derived); + tx.commit(); + s.close(); + } + public BasicHibernateAnnotationsTest(String x) { super( x ); @@ -353,7 +423,10 @@ public class BasicHibernateAnnotationsTest extends TestCase { Ransom.class, ZipCode.class, Flight.class, - Name.class + Name.class, + Car.class, + Peugot.class, + ContactDetails.class }; } diff --git a/annotations/src/test/java/org/hibernate/test/annotations/entity/Car.java b/annotations/src/test/java/org/hibernate/test/annotations/entity/Car.java new file mode 100644 index 0000000000..14502b730b --- /dev/null +++ b/annotations/src/test/java/org/hibernate/test/annotations/entity/Car.java @@ -0,0 +1,58 @@ +/* + * 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.test.annotations.entity; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import org.hibernate.annotations.Type; + + +/** + * Uses a custom type which is defined in a subclass + * @author Sharath Reddy + */ +@Entity +public class Car { + + @Id + @GeneratedValue + private int id; + @Type(type="definedInDerivedClass") + private String name; + public int getId() { + return id; + } + public void setId(int id) { + this.id = id; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + +} diff --git a/annotations/src/test/java/org/hibernate/test/annotations/entity/ContactDetails.java b/annotations/src/test/java/org/hibernate/test/annotations/entity/ContactDetails.java new file mode 100644 index 0000000000..9c47a040d2 --- /dev/null +++ b/annotations/src/test/java/org/hibernate/test/annotations/entity/ContactDetails.java @@ -0,0 +1,89 @@ +/* + * 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.test.annotations.entity; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; +import org.hibernate.annotations.TypeDefs; + + +@TypeDefs( + { + @TypeDef( + name = "overseasPhoneNumber", + typeClass = OverseasPhoneNumberType.class + + ), + @TypeDef( + defaultForType = PhoneNumber.class, + typeClass = PhoneNumberType.class + + ) + } +) + +/** + * @author Sharath Reddy + * + */ +@Entity +public class ContactDetails { + + @Id + @GeneratedValue + private int id; + + private PhoneNumber localPhoneNumber; + @Type(type="overseasPhoneNumber") + private PhoneNumber overseasPhoneNumber; + + public int getId() { + return id; + } + public void setId(int id) { + this.id = id; + } + public PhoneNumber getLocalPhoneNumber() { + return localPhoneNumber; + } + public void setLocalPhoneNumber(PhoneNumber localPhoneNumber) { + this.localPhoneNumber = localPhoneNumber; + } + public PhoneNumber getOverseasPhoneNumber() { + return overseasPhoneNumber; + } + public void setOverseasPhoneNumber(PhoneNumber overseasPhoneNumber) { + this.overseasPhoneNumber = overseasPhoneNumber; + } + + + + + + +} diff --git a/annotations/src/test/java/org/hibernate/test/annotations/entity/OverseasPhoneNumberType.java b/annotations/src/test/java/org/hibernate/test/annotations/entity/OverseasPhoneNumberType.java new file mode 100644 index 0000000000..b201ff6124 --- /dev/null +++ b/annotations/src/test/java/org/hibernate/test/annotations/entity/OverseasPhoneNumberType.java @@ -0,0 +1,98 @@ +/* + * 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.test.annotations.entity; + +import java.io.Serializable; +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; + +/** + * Used to persist and retrieve objects of type 'PhoneNumber' + * + * @author Sharath Reddy + */ +public class OverseasPhoneNumberType implements UserType { + + public int[] sqlTypes() { + return new int[]{Types.VARCHAR}; + } + + public Class returnedClass() { + return PhoneNumber.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 { + String result = rs.getString( names[0] ); + if ( rs.wasNull() ) return null; + return new PhoneNumber(result); + } + + public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException { + if ( value == null ) { + st.setNull( index, sqlTypes()[0] ); + } + else { + PhoneNumber phoneNumber = (PhoneNumber) value; + st.setString( index, getCountryCode() + phoneNumber.getNumber() ); + } + } + + + private String getCountryCode() { + return "041"; + } + + 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; + } + +} diff --git a/annotations/src/test/java/org/hibernate/test/annotations/entity/Peugot.java b/annotations/src/test/java/org/hibernate/test/annotations/entity/Peugot.java new file mode 100644 index 0000000000..fed4376181 --- /dev/null +++ b/annotations/src/test/java/org/hibernate/test/annotations/entity/Peugot.java @@ -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 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.test.annotations.entity; + +import javax.persistence.Entity; + +import org.hibernate.annotations.Parameter; +import org.hibernate.annotations.TypeDef; + +@TypeDef( + name = "definedInDerivedClass", + typeClass = CasterStringType.class, + parameters = { + @Parameter(name = "cast", value = "upper") + } +) + +/** + * Defines a custom type that is used in the + * base class. + * @author Sharath Reddy + * + */ +@Entity +public class Peugot extends Car { + +} diff --git a/annotations/src/test/java/org/hibernate/test/annotations/entity/PhoneNumber.java b/annotations/src/test/java/org/hibernate/test/annotations/entity/PhoneNumber.java new file mode 100644 index 0000000000..76edfa0887 --- /dev/null +++ b/annotations/src/test/java/org/hibernate/test/annotations/entity/PhoneNumber.java @@ -0,0 +1,42 @@ +/* + * 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.test.annotations.entity; + +public class PhoneNumber { + + private String number; + + public PhoneNumber(String val) { + number = val; + } + + public String getNumber() { + return number; + } + + public void setNumber(String number) { + this.number = number; + } + +} diff --git a/annotations/src/test/java/org/hibernate/test/annotations/entity/PhoneNumberType.java b/annotations/src/test/java/org/hibernate/test/annotations/entity/PhoneNumberType.java new file mode 100644 index 0000000000..5dcccbc403 --- /dev/null +++ b/annotations/src/test/java/org/hibernate/test/annotations/entity/PhoneNumberType.java @@ -0,0 +1,93 @@ +/* + * 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.test.annotations.entity; + +import java.io.Serializable; +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; + +/** + * Used to persist and retrieve objects of type 'PhoneNumber' + * + * @author Sharath Reddy + */ +public class PhoneNumberType implements UserType { + + public int[] sqlTypes() { + return new int[]{Types.VARCHAR}; + } + + public Class returnedClass() { + return PhoneNumber.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 { + String result = rs.getString( names[0] ); + if ( rs.wasNull() ) return null; + return new PhoneNumber(result); + } + + public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException { + if ( value == null ) { + st.setNull( index, sqlTypes()[0] ); + } + else { + PhoneNumber phoneNumber = (PhoneNumber) value; + st.setString( index, phoneNumber.getNumber() ); + } + } + + 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; + } + +}