From bb4c9bd411e45d67f60de95e7dd2f59f72f5f2d3 Mon Sep 17 00:00:00 2001 From: timis1 <12120641+timis1@users.noreply.github.com> Date: Fri, 2 Jun 2023 21:12:06 +0300 Subject: [PATCH] JAVA-20163 Update example for UserType/CompositeUserType (#14143) Co-authored-by: timis1 --- .../hibernate/customtypes/Address.java | 10 +++ .../hibernate/customtypes/AddressType.java | 46 +------------- .../hibernate/customtypes/OfficeEmployee.java | 6 +- .../customtypes/PhoneNumberType.java | 61 ++++++++----------- .../hibernate/customtypes/Salary.java | 3 +- .../hibernate/customtypes/SalaryType.java | 53 ++++------------ .../HibernateCustomTypesIntegrationTest.java | 10 ++- 7 files changed, 62 insertions(+), 127 deletions(-) diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/Address.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/Address.java index d559e5a6c2..b326363c60 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/Address.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/Address.java @@ -10,6 +10,16 @@ public class Address { private String country; private int zipCode; + public Address(String addressLine1, String addressLine2, String city, String country, int zipCode) { + this.addressLine1 = addressLine1; + this.addressLine2 = addressLine2; + this.city = city; + this.country = country; + this.zipCode = zipCode; + } + + public Address() {} + public String getAddressLine1() { return addressLine1; } diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/AddressType.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/AddressType.java index f50d8fd7cc..ea92d516ae 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/AddressType.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/AddressType.java @@ -2,19 +2,13 @@ package com.baeldung.hibernate.customtypes; import org.hibernate.HibernateException; import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.metamodel.spi.ValueAccess; import org.hibernate.usertype.CompositeUserType; -import org.hibernate.usertype.UserType; import java.io.Serializable; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; import java.util.Objects; -public class AddressType implements CompositeUserType
, UserType
{ +public class AddressType implements CompositeUserType
{ @Override public Object getPropertyValue(Address component, int property) throws HibernateException { @@ -39,7 +33,8 @@ public class AddressType implements CompositeUserType
, UserType
, UserType
returnedClass() { return Address.class; @@ -73,36 +63,6 @@ public class AddressType implements CompositeUserType
, UserType
{ +public class PhoneNumberType implements CompositeUserType { @Override - public int getSqlType() { - return Types.INTEGER; + public Object getPropertyValue(PhoneNumber component, int property) throws HibernateException { + switch (property) { + case 0: + return component.getCountryCode(); + case 1: + return component.getCityCode(); + case 2: + return component.getNumber(); + default: + throw new IllegalArgumentException(property + " is an invalid property index for class type " + component.getClass().getName()); + } + } + + @Override + public PhoneNumber instantiate(ValueAccess values, SessionFactoryImplementor sessionFactory) { + return new PhoneNumber(values.getValue(0, Integer.class), values.getValue(1, Integer.class), values.getValue(2,Integer.class)); + } + + @Override + public Class embeddable() { + return PhoneNumber.class; } @Override @@ -37,32 +54,6 @@ public class PhoneNumberType implements UserType { return x.hashCode(); } - @Override - public PhoneNumber nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException { - int countryCode = rs.getInt(position); - - if (rs.wasNull()) - return null; - - int cityCode = rs.getInt(position); - int number = rs.getInt(position); - - return new PhoneNumber(countryCode, cityCode, number); - } - - @Override - public void nullSafeSet(PreparedStatement st, PhoneNumber value, int index, SharedSessionContractImplementor session) throws SQLException { - if (Objects.isNull(value)) { - st.setNull(index, Types.INTEGER); - st.setNull(index+1, Types.INTEGER); - st.setNull(index+2, Types.INTEGER); - } else { - st.setInt(index, value.getCountryCode()); - st.setInt(index+1, value.getCityCode()); - st.setInt(index+2, value.getNumber()); - } - } - @Override public PhoneNumber deepCopy(PhoneNumber value) { if (Objects.isNull(value)) diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/Salary.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/Salary.java index f9a7ac5902..2402531869 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/Salary.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/Salary.java @@ -1,8 +1,9 @@ package com.baeldung.hibernate.customtypes; +import java.io.Serializable; import java.util.Objects; -public class Salary { +public class Salary implements Serializable { private Long amount; private String currency; diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/SalaryType.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/SalaryType.java index 69e34c1363..49294abe89 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/SalaryType.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/SalaryType.java @@ -1,10 +1,6 @@ package com.baeldung.hibernate.customtypes; -import org.hibernate.HibernateException; -import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; -import org.hibernate.metamodel.spi.ValueAccess; -import org.hibernate.usertype.CompositeUserType; import org.hibernate.usertype.DynamicParameterizedType; import org.hibernate.usertype.UserType; @@ -16,38 +12,13 @@ import java.sql.Types; import java.util.Objects; import java.util.Properties; -public class SalaryType implements UserType, CompositeUserType, DynamicParameterizedType { +public class SalaryType implements UserType, DynamicParameterizedType { private String localCurrency; - @Override - public Object getPropertyValue(Salary component, int property) throws HibernateException { - - switch (property) { - case 0: - return component.getAmount(); - case 1: - return component.getCurrency(); - default: - throw new IllegalArgumentException(property + - " is an invalid property index for class type " + - component.getClass().getName()); - } - } - - @Override - public Salary instantiate(ValueAccess values, SessionFactoryImplementor sessionFactory) { - return null; - } - - @Override - public Class embeddable() { - return Salary.class; - } - @Override public int getSqlType() { - return Types.BIGINT; + return Types.VARCHAR; } @Override @@ -74,12 +45,12 @@ public class SalaryType implements UserType, CompositeUserType, @Override public Salary nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException { Salary salary = new Salary(); - salary.setAmount(rs.getLong(position)); - if (rs.wasNull()) - return null; + String salaryValue = rs.getString(position); - salary.setCurrency(rs.getString(position)); + salary.setAmount(Long.parseLong(salaryValue.split(" ")[1])); + + salary.setCurrency(salaryValue.split(" ")[0]); return salary; } @@ -87,13 +58,11 @@ public class SalaryType implements UserType, CompositeUserType, @Override public void nullSafeSet(PreparedStatement st, Salary value, int index, SharedSessionContractImplementor session) throws SQLException { if (Objects.isNull(value)) - st.setNull(index, Types.BIGINT); + st.setNull(index, Types.VARCHAR); else { - - st.setLong(index, SalaryCurrencyConvertor.convert( - value.getAmount(), - value.getCurrency(), localCurrency)); - st.setString(index + 1, value.getCurrency()); + Long salaryValue = SalaryCurrencyConvertor.convert(value.getAmount(), + value.getCurrency(), localCurrency); + st.setString(index, value.getCurrency() + " " + salaryValue); } } @@ -117,7 +86,7 @@ public class SalaryType implements UserType, CompositeUserType, @Override public Serializable disassemble(Salary value) { - return (Serializable) deepCopy(value); + return deepCopy(value); } @Override diff --git a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/customtypes/HibernateCustomTypesIntegrationTest.java b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/customtypes/HibernateCustomTypesIntegrationTest.java index 9da3a90034..8e7a71c49b 100644 --- a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/customtypes/HibernateCustomTypesIntegrationTest.java +++ b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/customtypes/HibernateCustomTypesIntegrationTest.java @@ -11,10 +11,12 @@ import org.junit.Test; import jakarta.persistence.TypedQuery; import java.time.LocalDate; import java.util.HashMap; +import java.util.List; import java.util.Map; import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; public class HibernateCustomTypesIntegrationTest { @@ -74,12 +76,18 @@ public class HibernateCustomTypesIntegrationTest { doInHibernate(this::sessionFactory, session -> { session.save(e); + session.flush(); + session.refresh(e); TypedQuery query = session.createQuery("FROM OfficeEmployee OE WHERE OE.empAddress.zipCode = :pinCode", OfficeEmployee.class); query.setParameter("pinCode",100); - int size = query.getResultList().size(); + final List resultList = query.getResultList(); + int size = resultList.size(); assertEquals(1, size); + assertNotNull(resultList.get(0).getEmployeeNumber()); + assertNotNull(resultList.get(0).getEmpAddress()); + assertNotNull(resultList.get(0).getSalary()); }); }