JPA 2.1: Attribute Converter

本文详细解释了如何使用JPA2.1的AttributeConverter特性将自定义类类型转换为JPA支持的类型,包括实现步骤、应用实例以及解决实际项目中可能遇到的问题。通过例子展示了如何将一个列表类型的属性存储为一个字符串字段,并在从数据库检索时将其还原为列表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JPA 2.1: Attribute Converter

If you are using Hibernate, and want a customized type is supported in your Entity class, you could write a custom Hibernate Type.

JPA 2.1 brings a new feature named attribute converter, which can help you convert your custom class type to JPA supported type.

Reuse the Post entity class as example.

Create an Entity

<pre> @Entity @Table(name="POSTS") public class Post implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name="ID") private Long id; @Column(name="TITLE") private String title; @Column(name="BODY") private String body; @Temporal(javax.persistence.TemporalType.DATE) @Column(name="CREATED") private Date created; @Column(name="TAGS") private List&lt;String> tags=new ArrayList&lt;>(); } </pre>

Create an attribute converter

A new property tags is added, I want to use store tags list in to one column.

Create an attribute converter.

<pre> @Converter public class ListToStringConveter implements AttributeConverter&lt;List&lt;String>, String> { @Override public String convertToDatabaseColumn(List&lt;String> attribute) { if (attribute == null || attribute.isEmpty()) { return ""; } return StringUtils.join(attribute, ","); } @Override public List&lt;String> convertToEntityAttribute(String dbData) { if (dbData == null || dbData.trim().length() == 0) { return new ArrayList&lt;String>(); } String[] data = dbData.split(","); return Arrays.asList(data); } } </pre>

It is easy to understand, the tags property will be converted into a comma based string when store it into database, and tags property will be converted into a List when fetch it from database.

Apply Converter

You can use the autoApply attribute of the Converter to apply the converter to any supported type.

<pre> @Converter(autoApply=true) public class ListToStringConveter implements AttributeConverter&lt;List&lt;String>, String> {...} </pre>

It is dangerous in a real world project when there are some List you do not want to be converted.

Luckily, you can apply it on the property via @Convert annotation.

<pre> @Column(name="TAGS") @Convert(converter = ListToStringConveter.class) private List&lt;String> tags=new ArrayList&lt;>(); </pre>

You can also place it on class.

<pre> @Converts(value={ @Convert(attributeName="tags", converter = ListToStringConveter.class) }) public class Post implements Serializable {...} </pre>

An extra attributeName must be specified. You can declare several Converters for properties on an Entity class.

Converters also can be applied on:

  1. @Embeddable key of a OneToMany Map type property.
  2. @Embeded property
  3. @ElementCollection property

Summary

This feature is very useful when you want use a JPA supported type to store your custom class, especially, convert an unsupported type to JPA support type, for example, such as Joda Datetime/Java 8 new Date objects are not supported in JPA 2.1 yet, you can use a converter to convert it to java.util.Date type which is supported by JPA.

The sample codes are hosted on my github.com account, check out and play it yourself.

https://github.com/hantsy/ee7-sandbox

When you run the project(jpa-converter) on Glassfish 4.0 and you could get an exception.

<pre> java.lang.RuntimeException: unable to create policy context directory. </pre>

This is a known issue of Glassfish 4.0, the fix should be included in the next release. I am using an Nightly version to overcome this barrier.

转载于:https://my.oschina.net/hantsy/blog/179921

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值