You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 11:59:54