HHH-3000 Allow a TypeDef to be associated with a class (Sharath Reddy)
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@17626 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
460a7ace1c
commit
c6a32b933d
|
@ -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 {};
|
||||
}
|
||||
|
|
|
@ -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,9 +1003,23 @@ public final class AnnotationBinder {
|
|||
for (Parameter param : defAnn.parameters()) {
|
||||
params.setProperty( param.name(), param.value() );
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -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(
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -156,4 +156,7 @@ public interface ExtendedMappings extends Mappings {
|
|||
public void addAnyMetaDef(AnyMetaDef defAnn) throws AnnotationException;
|
||||
|
||||
public AnyMetaDef getAnyMetaDef(String name);
|
||||
|
||||
public boolean isInSecondPass();
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
public SimpleValue fillSimpleValue(SimpleValue 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 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;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -342,6 +342,76 @@ public class BasicHibernateAnnotationsTest extends TestCase {
|
|||
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
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue