Skip to content

Commit

Permalink
HHH-7310 Resolution of types registered in type registry does not wor…
Browse files Browse the repository at this point in the history
…k properly for Properties of @embeddable types
  • Loading branch information
stliu committed Jul 10, 2012
1 parent 3e47862 commit 65d1724
Show file tree
Hide file tree
Showing 10 changed files with 633 additions and 23 deletions.
21 changes: 4 additions & 17 deletions hibernate-core/src/main/java/org/hibernate/mapping/Component.java
Expand Up @@ -42,6 +42,7 @@
import org.hibernate.property.Setter;
import org.hibernate.tuple.component.ComponentMetamodel;
import org.hibernate.type.Type;
import org.hibernate.type.TypeFactory;

/**
* The mapping for a component, composite element,
Expand Down Expand Up @@ -166,25 +167,11 @@ public void setDynamic(boolean dynamic) {
this.dynamic = dynamic;
}

private Type type;

public Type getType() throws MappingException {
// added this caching as I noticed that getType() is being called multiple times...
if ( type == null ) {
type = buildType();
}
return type;
}

private Type buildType() {
// TODO : temporary initial step towards HHH-1907
ComponentMetamodel metamodel = new ComponentMetamodel( this );
if ( isEmbedded() ) {
return getMappings().getTypeResolver().getTypeFactory().embeddedComponent( metamodel );
}
else {
return getMappings().getTypeResolver().getTypeFactory().component( metamodel );
}
final ComponentMetamodel metamodel = new ComponentMetamodel( this );
final TypeFactory factory = getMappings().getTypeResolver().getTypeFactory();
return isEmbedded() ? factory.embeddedComponent( metamodel ) : factory.component( metamodel );
}

public void setTypeUsingReflection(String className, String propertyName)
Expand Down
Expand Up @@ -77,12 +77,10 @@ public ComponentMetamodel(Component component) {
// todo : move this to SF per HHH-3517; also see HHH-1907 and ComponentMetamodel
final ComponentTuplizerFactory componentTuplizerFactory = new ComponentTuplizerFactory();
final String tuplizerClassName = component.getTuplizerImplClassName( entityMode );
if ( tuplizerClassName == null ) {
componentTuplizer = componentTuplizerFactory.constructDefaultTuplizer( entityMode, component );
}
else {
componentTuplizer = componentTuplizerFactory.constructTuplizer( tuplizerClassName, component );
}
this.componentTuplizer = tuplizerClassName == null ? componentTuplizerFactory.constructDefaultTuplizer(
entityMode,
component
) : componentTuplizerFactory.constructTuplizer( tuplizerClassName, component );
}

public boolean isKey() {
Expand Down
@@ -0,0 +1,47 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.test.annotations.embeddables;

import java.io.Serializable;
import java.math.BigDecimal;

/**
* @author Chris Pheby
*/
public class DollarValue implements Serializable {

private static final long serialVersionUID = -416056386419355705L;

private BigDecimal amount;

public DollarValue() {};

public DollarValue(BigDecimal amount) {
this.amount = amount;
}

public BigDecimal getAmount() {
return amount;
}
}
@@ -0,0 +1,112 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.test.annotations.embeddables;

import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.usertype.UserType;

/**
* @author Chris Pheby
*/
public class DollarValueUserType implements UserType {

@Override
public int[] sqlTypes() {
return new int[] {Types.BIGINT};
}

@Override
public Class<DollarValue> returnedClass() {
return DollarValue.class;
}

@Override
public boolean equals(Object x, Object y) throws HibernateException {
if (!(x instanceof DollarValue) || !(y instanceof DollarValue)) {
throw new HibernateException("Expected DollarValue");
}
return ((DollarValue)x).getAmount().equals(((DollarValue)y).getAmount());
}

@Override
public int hashCode(Object x) throws HibernateException {
if (!(x instanceof DollarValue)) {
throw new HibernateException("Expected DollarValue");
}
return ((DollarValue)x).getAmount().hashCode();
}

@Override
public DollarValue nullSafeGet(ResultSet rs, String[] names,
SessionImplementor session, Object owner)
throws HibernateException, SQLException {

DollarValue result = new DollarValue(rs.getBigDecimal(rs.findColumn(names[0])));
return result;
}

@Override
public void nullSafeSet(PreparedStatement st, Object value, int index,
SessionImplementor session) throws HibernateException, SQLException {

st.setBigDecimal(index, ((DollarValue)value).getAmount());
}

@Override
public Object deepCopy(Object value) throws HibernateException {
DollarValue result = new DollarValue();

return result;
}

@Override
public boolean isMutable() {
return false;
}

@Override
public Serializable disassemble(Object value) throws HibernateException {
return null;
}

@Override
public Object assemble(Serializable cached, Object owner)
throws HibernateException {
return null;
}

@Override
public Object replace(Object original, Object target, Object owner)
throws HibernateException {
return null;
}
}
@@ -0,0 +1,126 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.test.annotations.embeddables;

import static org.junit.Assert.assertEquals;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.exception.GenericJDBCException;
import org.hibernate.integrator.internal.IntegratorServiceImpl;
import org.hibernate.integrator.spi.Integrator;
import org.hibernate.integrator.spi.IntegratorService;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.hibernate.service.classloading.internal.ClassLoaderServiceImpl;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.service.internal.BootstrapServiceRegistryImpl;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.Test;

/**
* @author Chris Pheby
*/
public class EmbeddableIntegratorTest extends BaseUnitTestCase {

/**
* Throws a mapping exception because DollarValue is not mapped
*/
@Test(expected=GenericJDBCException.class)
public void testWithoutIntegrator() {

ServiceRegistry reg = new ServiceRegistryBuilder(new BootstrapServiceRegistryImpl())
.buildServiceRegistry();

SessionFactory sf = new Configuration()
.addAnnotatedClass( Investor.class )

.buildSessionFactory(reg);

Session sess = sf.openSession();
Investor myInv = getInvestor();
myInv.setId(1L);

sess.save(myInv);
sess.flush();
sess.clear();

Investor inv = (Investor) sess.get(Investor.class, 1L);
assertEquals(new BigDecimal("100"), inv.getInvestments().get(0).getAmount().getAmount());

sess.close();
}

@Test
public void testWithIntegrator() {

LinkedHashSet<Integrator> providedIntegrators = new LinkedHashSet<Integrator>();
providedIntegrators.add(new InvestorIntegrator());
ClassLoaderService classLoaderService = new ClassLoaderServiceImpl();
IntegratorService integratorService = new IntegratorServiceImpl(providedIntegrators, classLoaderService);

ServiceRegistry reg = new ServiceRegistryBuilder(new BootstrapServiceRegistryImpl(
classLoaderService,
integratorService)).buildServiceRegistry();

SessionFactory sf = new Configuration()
.addAnnotatedClass( Investor.class )

.setProperty("hibernate.hbm2ddl.auto", "create-drop")
.buildSessionFactory(reg);

Session sess = sf.openSession();
Investor myInv = getInvestor();
myInv.setId(2L);

sess.save(myInv);
sess.flush();
sess.clear();

Investor inv = (Investor) sess.get(Investor.class, 2L);
assertEquals(new BigDecimal("100"), inv.getInvestments().get(0).getAmount().getAmount());

sess.close();
}

private Investor getInvestor() {
Investor i = new Investor();
List<Investment> investments = new ArrayList<Investment>();
Investment i1 = new Investment();
i1.setAmount(new DollarValue(new BigDecimal("100")));
i1.setDate(new MyDate(new Date()));
i1.setDescription("Test Investment");
investments.add(i1);
i.setInvestments(investments);

return i;
}
}

0 comments on commit 65d1724

Please sign in to comment.