HHH-4512 TypeDef annotation should support both 'name' and 'defaultForType' attributes
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@17814 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
00fbf234e1
commit
d26c002258
|
@ -38,8 +38,7 @@ import java.lang.annotation.Target;
|
|||
@Retention(RUNTIME)
|
||||
public @interface TypeDef {
|
||||
String name() default "";
|
||||
Class<?> typeClass();
|
||||
Class<?> defaultForType() default void.class;
|
||||
|
||||
Class<?> typeClass();
|
||||
Parameter[] parameters() default {};
|
||||
}
|
||||
|
|
|
@ -1006,19 +1006,20 @@ public final class AnnotationBinder {
|
|||
}
|
||||
|
||||
if (BinderHelper.isDefault(defAnn.name()) && defAnn.defaultForType().equals(void.class)) {
|
||||
throw new AnnotationException("Both name and defaultForType attributes cannot be set in a TypeDef");
|
||||
throw new AnnotationException(
|
||||
"Either name or defaultForType (or both) attribute should be set in TypeDef having typeClass " +
|
||||
defAnn.typeClass().getName());
|
||||
}
|
||||
|
||||
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)) {
|
||||
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");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -28,11 +28,13 @@ import java.math.BigDecimal;
|
|||
import java.util.Currency;
|
||||
import java.util.Date;
|
||||
|
||||
import org.hibernate.AnnotationException;
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Query;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.cfg.AnnotationConfiguration;
|
||||
import org.hibernate.test.annotations.TestCase;
|
||||
|
||||
/**
|
||||
|
@ -403,18 +405,12 @@ public class BasicHibernateAnnotationsTest extends TestCase {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
public void testTypeDefNameAndDefaultForTypeAttributes() {
|
||||
|
||||
ContactDetails contactDetails = new ContactDetails();
|
||||
contactDetails.setLocalPhoneNumber(new PhoneNumber("999999"));
|
||||
contactDetails.setOverseasPhoneNumber(new PhoneNumber("111111"));
|
||||
contactDetails.setOverseasPhoneNumber(
|
||||
new OverseasPhoneNumber("041", "111111"));
|
||||
|
||||
Session s = openSession();
|
||||
Transaction tx = s.beginTransaction();
|
||||
|
@ -432,12 +428,25 @@ public class BasicHibernateAnnotationsTest extends TestCase {
|
|||
s.delete(contactDetails);
|
||||
tx.commit();
|
||||
s.close();
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void testTypeDefWithoutNameAndDefaultForTypeAttributes() {
|
||||
|
||||
try {
|
||||
AnnotationConfiguration config = new AnnotationConfiguration();
|
||||
config.addAnnotatedClass(LocalContactDetails.class);
|
||||
config.buildSessionFactory();
|
||||
fail("Did not throw expected exception");
|
||||
}
|
||||
catch( AnnotationException ex ) {
|
||||
assertEquals(
|
||||
"Either name or defaultForType (or both) attribute should be set in TypeDef having typeClass org.hibernate.test.annotations.entity.PhoneNumberType",
|
||||
ex.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A custom type is used in the base class, but defined in the derived class.
|
||||
|
|
|
@ -26,25 +26,13 @@ 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
|
||||
|
||||
)
|
||||
}
|
||||
@TypeDef(
|
||||
name = "phoneNumber",
|
||||
defaultForType = PhoneNumber.class,
|
||||
typeClass = PhoneNumberType.class
|
||||
)
|
||||
|
||||
/**
|
||||
|
@ -59,8 +47,8 @@ public class ContactDetails {
|
|||
private int id;
|
||||
|
||||
private PhoneNumber localPhoneNumber;
|
||||
@Type(type="overseasPhoneNumber")
|
||||
private PhoneNumber overseasPhoneNumber;
|
||||
@Type(type="phoneNumber")
|
||||
private OverseasPhoneNumber overseasPhoneNumber;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
|
@ -74,16 +62,11 @@ public class ContactDetails {
|
|||
public void setLocalPhoneNumber(PhoneNumber localPhoneNumber) {
|
||||
this.localPhoneNumber = localPhoneNumber;
|
||||
}
|
||||
public PhoneNumber getOverseasPhoneNumber() {
|
||||
public OverseasPhoneNumber getOverseasPhoneNumber() {
|
||||
return overseasPhoneNumber;
|
||||
}
|
||||
public void setOverseasPhoneNumber(PhoneNumber overseasPhoneNumber) {
|
||||
public void setOverseasPhoneNumber(OverseasPhoneNumber overseasPhoneNumber) {
|
||||
this.overseasPhoneNumber = overseasPhoneNumber;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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, 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.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;
|
||||
|
||||
@TypeDef(
|
||||
typeClass = PhoneNumberType.class
|
||||
)
|
||||
|
||||
/**
|
||||
* @author Sharath Reddy
|
||||
*
|
||||
*/
|
||||
@Entity
|
||||
public class LocalContactDetails {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private int id;
|
||||
|
||||
private PhoneNumber localPhoneNumber;
|
||||
@Type(type="phoneNumber")
|
||||
private OverseasPhoneNumber 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 OverseasPhoneNumber getOverseasPhoneNumber() {
|
||||
return overseasPhoneNumber;
|
||||
}
|
||||
public void setOverseasPhoneNumber(OverseasPhoneNumber overseasPhoneNumber) {
|
||||
this.overseasPhoneNumber = overseasPhoneNumber;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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, 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.test.annotations.entity;
|
||||
|
||||
/**
|
||||
* @author Sharath Reddy
|
||||
*/
|
||||
public class OverseasPhoneNumber extends PhoneNumber {
|
||||
|
||||
public OverseasPhoneNumber(String areaCode, String val) {
|
||||
super(areaCode + val);
|
||||
}
|
||||
|
||||
public OverseasPhoneNumber(String val) {
|
||||
super(val);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -42,7 +42,7 @@ public class PhoneNumberType implements UserType {
|
|||
return new int[]{Types.VARCHAR};
|
||||
}
|
||||
|
||||
public Class returnedClass() {
|
||||
public Class<?> returnedClass() {
|
||||
return PhoneNumber.class;
|
||||
}
|
||||
|
||||
|
@ -57,17 +57,24 @@ public class PhoneNumberType implements UserType {
|
|||
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);
|
||||
|
||||
if (result.length() <= 6) {
|
||||
return new PhoneNumber(result);
|
||||
}
|
||||
else {
|
||||
return new OverseasPhoneNumber(result);
|
||||
}
|
||||
}
|
||||
|
||||
public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
|
||||
if ( value == null ) {
|
||||
st.setNull( index, sqlTypes()[0] );
|
||||
return;
|
||||
}
|
||||
else {
|
||||
PhoneNumber phoneNumber = (PhoneNumber) value;
|
||||
st.setString( index, phoneNumber.getNumber() );
|
||||
}
|
||||
|
||||
PhoneNumber phoneNumber = (PhoneNumber) value;
|
||||
String number = phoneNumber.getNumber();
|
||||
st.setString( index, number);
|
||||
}
|
||||
|
||||
public Object deepCopy(Object value) throws HibernateException {
|
||||
|
|
Loading…
Reference in New Issue