OpenJPA中@Converter标注的List<String>字段未持久化问题
问题:OpenJPA无法识别@Converter处理List字段
开发Web应用后端时,尝试通过@Converter将List<String>类型字段持久化为String类型,代码编译正常,但部署时收到如下警告,字段被当作非持久化处理:
WARNING [main] null.openjpa.Runtime Fields "com.barbeeloft.webapp.model.Employee.training" are not a default persistent type, and do not have any annotations indicating their persistence strategy. They will be treated as non-persistent. If you intended for these fields to be persistent, be sure to annotate them appropriately or declare them in orm.xml. Otherwise annotate them with @Transient.
相关代码
Converter实现代码
@Converter(autoApply=true) public class StringListConverter implements AttributeConverter<List<String>,String> { private static final String SPLIT_CHAR = ";"; @Override public String convertToDatabaseColumn( List<String> list ) { String s = list != null ? String.join( SPLIT_CHAR, list ) : ""; System.out.println("in convertToDatabaseColumn("+ s +")" ); return s; }; @Override public List<String> convertToEntityAttribute( String string ) { List<String> l = string != null ? new ArrayList<String>( Arrays.asList( string.split(SPLIT_CHAR)) ) : new ArrayList<String>(); System.out.println( "in convertToEntityAttribute("+ l +")" ); return l; }; }
Employee实体类字段定义
@Column(length=128,name="TRAINING",columnDefinition = "VARCHAR(128) NOT NULL") @Convert(converter=StringListConverter.class,attributeName="training") private List<String> training = new ArrayList<>();
完整Employee实体类
package com.barbeeloft.webapp.model; import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Convert; import jakarta.persistence.Column; import jakarta.persistence.Table; import java.io.Serializable; import java.util.List; import java.util.ArrayList; import com.barbeeloft.webapp.utils.StringListConverter; @Entity @Table(name="EMPLOYEE") public class Employee implements Serializable { @Id @Column(length=6,name="ID") private String id; @Column(length=128,name="TRAINING",columnDefinition = "VARCHAR(128) NOT NULL") @Convert(converter=StringListConverter.class,attributeName="training") private List<String> training = new ArrayList<String>(); public String getId() { return id; } public void setId(String id) { this.id = id; } public List<String> getTraining() { return training; } public void setTraining(List<String> training) { this.training = training; } }
环境信息
- Apache TomEE MicroProfile 9.1.2
- OpenJPA 3.2.2-jakarta(集成于TomEE)
- NetBeans IDE 20
- OpenJDK 21.0.1(Mac系统)
已尝试方案:给Converter添加autoApply=true、调整@Column属性、设置@Convert的attributeName参数,问题仍未解决。
解决方案
1. 移除@Convert的attributeName参数
attributeName是类级别@Convert时指定目标字段的参数,字段级别使用会导致OpenJPA解析异常。修改字段注解:
@Column(length=128,name="TRAINING",columnDefinition = "VARCHAR(128) NOT NULL") @Convert(converter=StringListConverter.class) private List<String> training = new ArrayList<>();
2. 显式声明Converter类
确保OpenJPA扫描到Converter,在persistence.xml中添加Converter的类声明:
<persistence-unit name="YourPU" transaction-type="JTA"> <jta-data-source>jdbc/YourDataSource</jta-data-source> <class>com.barbeeloft.webapp.model.Employee</class> <class>com.barbeeloft.webapp.utils.StringListConverter</class> <!-- 其他配置 --> </persistence-unit>
3. 校验注解包一致性
确认所有JPA注解都使用jakarta.persistence.*包,避免混用旧的javax.persistence.*包(OpenJPA 3.x对应Jakarta Persistence 3.0)。
4. 清理部署缓存
删除TomEE的work目录、项目的target编译目录,重新编译部署,避免旧文件干扰。
5. 检查OpenJPA配置
确保persistence.xml中没有禁用Converter的配置,比如openjpa.Converter=false这类参数。
内容的提问来源于stack exchange,提问作者ChrisB
相关产品推荐
相关产品推荐

