Skip to content

Commit d7d751c

Browse files
timis1timis1
andauthored
JAVA-20163 Update example for UserType/CompositeUserType (eugenp#14143)
Co-authored-by: timis1 <[email protected]>
1 parent 9032d8e commit d7d751c

File tree

7 files changed

+62
-127
lines changed

7 files changed

+62
-127
lines changed

persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/Address.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@ public class Address {
1010
private String country;
1111
private int zipCode;
1212

13+
public Address(String addressLine1, String addressLine2, String city, String country, int zipCode) {
14+
this.addressLine1 = addressLine1;
15+
this.addressLine2 = addressLine2;
16+
this.city = city;
17+
this.country = country;
18+
this.zipCode = zipCode;
19+
}
20+
21+
public Address() {}
22+
1323
public String getAddressLine1() {
1424
return addressLine1;
1525
}

persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/AddressType.java

Lines changed: 3 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,13 @@
22

33
import org.hibernate.HibernateException;
44
import org.hibernate.engine.spi.SessionFactoryImplementor;
5-
import org.hibernate.engine.spi.SharedSessionContractImplementor;
65
import org.hibernate.metamodel.spi.ValueAccess;
76
import org.hibernate.usertype.CompositeUserType;
8-
import org.hibernate.usertype.UserType;
97

108
import java.io.Serializable;
11-
import java.sql.PreparedStatement;
12-
import java.sql.ResultSet;
13-
import java.sql.SQLException;
14-
import java.sql.Types;
159
import java.util.Objects;
1610

17-
public class AddressType implements CompositeUserType<Address>, UserType<Address> {
11+
public class AddressType implements CompositeUserType<Address> {
1812

1913
@Override
2014
public Object getPropertyValue(Address component, int property) throws HibernateException {
@@ -39,19 +33,15 @@ public Object getPropertyValue(Address component, int property) throws Hibernate
3933

4034
@Override
4135
public Address instantiate(ValueAccess values, SessionFactoryImplementor sessionFactory) {
42-
return null;
36+
return new Address(values.getValue(0, String.class), values.getValue(1,String.class), values.getValue(2, String.class),
37+
values.getValue(3, String.class), values.getValue(4,Integer.class));
4338
}
4439

4540
@Override
4641
public Class<?> embeddable() {
4742
return Address.class;
4843
}
4944

50-
@Override
51-
public int getSqlType() {
52-
return Types.VARCHAR;
53-
}
54-
5545
@Override
5646
public Class<Address> returnedClass() {
5747
return Address.class;
@@ -73,36 +63,6 @@ public int hashCode(Address x) {
7363
return x.hashCode();
7464
}
7565

76-
@Override
77-
public Address nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException {
78-
Address empAdd = new Address();
79-
empAdd.setAddressLine1(rs.getString(position));
80-
81-
if (rs.wasNull())
82-
return null;
83-
84-
empAdd.setAddressLine2(rs.getString(position));
85-
empAdd.setCity(rs.getString(position));
86-
empAdd.setCountry(rs.getString(position));
87-
empAdd.setZipCode(rs.getInt(position));
88-
89-
return empAdd;
90-
}
91-
92-
@Override
93-
public void nullSafeSet(PreparedStatement st, Address value, int index, SharedSessionContractImplementor session) throws SQLException {
94-
if (Objects.isNull(value))
95-
st.setNull(index, Types.VARCHAR);
96-
else {
97-
98-
st.setString(index, value.getAddressLine1());
99-
st.setString(index + 1, value.getAddressLine2());
100-
st.setString(index + 2, value.getCity());
101-
st.setString(index + 3, value.getCountry());
102-
st.setInt(index + 4, value.getZipCode());
103-
}
104-
}
105-
10666
@Override
10767
public Address deepCopy(Address value) {
10868
if (Objects.isNull(value))

persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/OfficeEmployee.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public class OfficeEmployee {
3434
@AttributeOverride(name = "cityCode", column = @Column(name = "city_code")),
3535
@AttributeOverride(name = "number", column = @Column(name = "number"))
3636
})
37-
@Type(value = PhoneNumberType.class)
37+
@CompositeType(value = PhoneNumberType.class)
3838
private PhoneNumber employeeNumber;
3939

4040
@CompositeType(value = com.baeldung.hibernate.customtypes.AddressType.class)
@@ -49,10 +49,6 @@ public class OfficeEmployee {
4949

5050
@Type(value = com.baeldung.hibernate.customtypes.SalaryType.class,
5151
parameters = {@Parameter(name = "currency", value = "USD")})
52-
@AttributeOverrides({
53-
@AttributeOverride(name = "amount", column = @Column(name = "amount")),
54-
@AttributeOverride(name = "currency", column = @Column(name = "currency"))
55-
})
5652
private Salary salary;
5753

5854
public Salary getSalary() {

persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/PhoneNumberType.java

Lines changed: 26 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,37 @@
11
package com.baeldung.hibernate.customtypes;
22

3-
import org.hibernate.engine.spi.SharedSessionContractImplementor;
4-
import org.hibernate.usertype.UserType;
3+
import org.hibernate.HibernateException;
4+
import org.hibernate.engine.spi.SessionFactoryImplementor;
5+
import org.hibernate.metamodel.spi.ValueAccess;
6+
import org.hibernate.usertype.CompositeUserType;
57

68
import java.io.Serializable;
7-
import java.sql.PreparedStatement;
8-
import java.sql.ResultSet;
9-
import java.sql.SQLException;
10-
import java.sql.Types;
119
import java.util.Objects;
1210

13-
public class PhoneNumberType implements UserType<PhoneNumber> {
11+
public class PhoneNumberType implements CompositeUserType<PhoneNumber> {
1412

1513
@Override
16-
public int getSqlType() {
17-
return Types.INTEGER;
14+
public Object getPropertyValue(PhoneNumber component, int property) throws HibernateException {
15+
switch (property) {
16+
case 0:
17+
return component.getCountryCode();
18+
case 1:
19+
return component.getCityCode();
20+
case 2:
21+
return component.getNumber();
22+
default:
23+
throw new IllegalArgumentException(property + " is an invalid property index for class type " + component.getClass().getName());
24+
}
25+
}
26+
27+
@Override
28+
public PhoneNumber instantiate(ValueAccess values, SessionFactoryImplementor sessionFactory) {
29+
return new PhoneNumber(values.getValue(0, Integer.class), values.getValue(1, Integer.class), values.getValue(2,Integer.class));
30+
}
31+
32+
@Override
33+
public Class<?> embeddable() {
34+
return PhoneNumber.class;
1835
}
1936

2037
@Override
@@ -37,32 +54,6 @@ public int hashCode(PhoneNumber x) {
3754
return x.hashCode();
3855
}
3956

40-
@Override
41-
public PhoneNumber nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException {
42-
int countryCode = rs.getInt(position);
43-
44-
if (rs.wasNull())
45-
return null;
46-
47-
int cityCode = rs.getInt(position);
48-
int number = rs.getInt(position);
49-
50-
return new PhoneNumber(countryCode, cityCode, number);
51-
}
52-
53-
@Override
54-
public void nullSafeSet(PreparedStatement st, PhoneNumber value, int index, SharedSessionContractImplementor session) throws SQLException {
55-
if (Objects.isNull(value)) {
56-
st.setNull(index, Types.INTEGER);
57-
st.setNull(index+1, Types.INTEGER);
58-
st.setNull(index+2, Types.INTEGER);
59-
} else {
60-
st.setInt(index, value.getCountryCode());
61-
st.setInt(index+1, value.getCityCode());
62-
st.setInt(index+2, value.getNumber());
63-
}
64-
}
65-
6657
@Override
6758
public PhoneNumber deepCopy(PhoneNumber value) {
6859
if (Objects.isNull(value))

persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/Salary.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package com.baeldung.hibernate.customtypes;
22

3+
import java.io.Serializable;
34
import java.util.Objects;
45

5-
public class Salary {
6+
public class Salary implements Serializable {
67

78
private Long amount;
89
private String currency;

persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/SalaryType.java

Lines changed: 11 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
package com.baeldung.hibernate.customtypes;
22

3-
import org.hibernate.HibernateException;
4-
import org.hibernate.engine.spi.SessionFactoryImplementor;
53
import org.hibernate.engine.spi.SharedSessionContractImplementor;
6-
import org.hibernate.metamodel.spi.ValueAccess;
7-
import org.hibernate.usertype.CompositeUserType;
84
import org.hibernate.usertype.DynamicParameterizedType;
95
import org.hibernate.usertype.UserType;
106

@@ -16,38 +12,13 @@
1612
import java.util.Objects;
1713
import java.util.Properties;
1814

19-
public class SalaryType implements UserType<Salary>, CompositeUserType<Salary>, DynamicParameterizedType {
15+
public class SalaryType implements UserType<Salary>, DynamicParameterizedType {
2016

2117
private String localCurrency;
2218

23-
@Override
24-
public Object getPropertyValue(Salary component, int property) throws HibernateException {
25-
26-
switch (property) {
27-
case 0:
28-
return component.getAmount();
29-
case 1:
30-
return component.getCurrency();
31-
default:
32-
throw new IllegalArgumentException(property +
33-
" is an invalid property index for class type " +
34-
component.getClass().getName());
35-
}
36-
}
37-
38-
@Override
39-
public Salary instantiate(ValueAccess values, SessionFactoryImplementor sessionFactory) {
40-
return null;
41-
}
42-
43-
@Override
44-
public Class<?> embeddable() {
45-
return Salary.class;
46-
}
47-
4819
@Override
4920
public int getSqlType() {
50-
return Types.BIGINT;
21+
return Types.VARCHAR;
5122
}
5223

5324
@Override
@@ -74,26 +45,24 @@ public int hashCode(Salary x) {
7445
@Override
7546
public Salary nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException {
7647
Salary salary = new Salary();
77-
salary.setAmount(rs.getLong(position));
7848

79-
if (rs.wasNull())
80-
return null;
49+
String salaryValue = rs.getString(position);
50+
51+
salary.setAmount(Long.parseLong(salaryValue.split(" ")[1]));
8152

82-
salary.setCurrency(rs.getString(position));
53+
salary.setCurrency(salaryValue.split(" ")[0]);
8354

8455
return salary;
8556
}
8657

8758
@Override
8859
public void nullSafeSet(PreparedStatement st, Salary value, int index, SharedSessionContractImplementor session) throws SQLException {
8960
if (Objects.isNull(value))
90-
st.setNull(index, Types.BIGINT);
61+
st.setNull(index, Types.VARCHAR);
9162
else {
92-
93-
st.setLong(index, SalaryCurrencyConvertor.convert(
94-
value.getAmount(),
95-
value.getCurrency(), localCurrency));
96-
st.setString(index + 1, value.getCurrency());
63+
Long salaryValue = SalaryCurrencyConvertor.convert(value.getAmount(),
64+
value.getCurrency(), localCurrency);
65+
st.setString(index, value.getCurrency() + " " + salaryValue);
9766
}
9867
}
9968

@@ -117,7 +86,7 @@ public boolean isMutable() {
11786

11887
@Override
11988
public Serializable disassemble(Salary value) {
120-
return (Serializable) deepCopy(value);
89+
return deepCopy(value);
12190
}
12291

12392
@Override

persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/customtypes/HibernateCustomTypesIntegrationTest.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111
import jakarta.persistence.TypedQuery;
1212
import java.time.LocalDate;
1313
import java.util.HashMap;
14+
import java.util.List;
1415
import java.util.Map;
1516

1617
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
1718
import static org.junit.Assert.assertEquals;
19+
import static org.junit.Assert.assertNotNull;
1820
import static org.junit.Assert.assertTrue;
1921

2022
public class HibernateCustomTypesIntegrationTest {
@@ -74,12 +76,18 @@ public void givenEmployee_whenCustomTypeInQuery_thenReturnEntity() {
7476

7577
doInHibernate(this::sessionFactory, session -> {
7678
session.save(e);
79+
session.flush();
80+
session.refresh(e);
7781

7882
TypedQuery<OfficeEmployee> query = session.createQuery("FROM OfficeEmployee OE WHERE OE.empAddress.zipCode = :pinCode", OfficeEmployee.class);
7983
query.setParameter("pinCode",100);
80-
int size = query.getResultList().size();
84+
final List<OfficeEmployee> resultList = query.getResultList();
85+
int size = resultList.size();
8186

8287
assertEquals(1, size);
88+
assertNotNull(resultList.get(0).getEmployeeNumber());
89+
assertNotNull(resultList.get(0).getEmpAddress());
90+
assertNotNull(resultList.get(0).getSalary());
8391
});
8492

8593
}

0 commit comments

Comments
 (0)