EclipseLink JPA报错:找不到java.util.Setjava.time.DayOfWeek类求助
问题:EclipseLink生成DDL时抛出ClassNotFoundException:java.util.Setjava.time.DayOfWeek
实体类字段定义
@Column(name="DAYS_BITMAP", length=7) @Convert(converter=DaysOfWeekSetToStringConverter.class) private Set<DayOfWeek> daysRunning;
转换器实现
import java.time.DayOfWeek; import java.util.HashSet; import java.util.Set; import javax.persistence.AttributeConverter; import javax.persistence.Converter; @Converter(autoApply = false) public class DaysOfWeekSetToStringConverter implements AttributeConverter<Set<DayOfWeek>, String> { @Override public String convertToDatabaseColumn(Set<DayOfWeek> attribute) { char[] result = "0000000".toCharArray(); for (DayOfWeek dow : attribute) { result[dow.getValue()-1] = '1'; } return new String(result); } @Override public Set<DayOfWeek> convertToEntityAttribute(String dbData) { Set<DayOfWeek> results = new HashSet<>(); char[] daysOfWeekMonToSun = dbData.toCharArray(); for (int i=0;i<7;i++) // 7 days in a week { if (daysOfWeekMonToSun[i] == '1') { results.add(DayOfWeek.of(i+1)); // days of week are indexed 1 = Monday, 7 = Sunday } } return results; } }
错误日志
[EL Fine]: server: Configured server platform: org.eclipse.persistence.platform.server.NoServerPlatform [EL Fine]: metadata: java.lang.ClassNotFoundException: java.util.Setjava.time.DayOfWeek at java.net.URLClassLoader.findClass(URLClassLoader.java:387) at java.lang.ClassLoader.loadClass(ClassLoader.java:418) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352) at java.lang.ClassLoader.loadClass(ClassLoader.java:351) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:264) at org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataAsmFactory.getVirtualMetadataClass(MetadataAsmFactory.java:542) at org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataAsmFactory.buildClassMetadata(MetadataAsmFactory.java:143) at org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataAsmFactory.getMetadataClass(MetadataAsmFactory.java:177) at org.eclipse.persistence.internal.jpa.metadata.ORMetadata.getMetadataClass(ORMetadata.java:408) at org.eclipse.persistence.internal.jpa.metadata.ORMetadata.getMetadataClass(ORMetadata.java:400) at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.ConverterAccessor.initClassificationClasses(ConverterAccessor.java:179) at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.ConverterAccessor.<init>(ConverterAccessor.java:85) at org.eclipse.persistence.internal.jpa.metadata.MetadataProcessor.initPersistenceUnitClasses(MetadataProcessor.java:378) at org.eclipse.persistence.internal.jpa.metadata.MetadataProcessor.processEntityMappings(MetadataProcessor.java:563) at org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processORMetadata(PersistenceUnitProcessor.java:625) at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:2001) at org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.callPredeploy(JPAInitializer.java:104) at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactoryImpl(PersistenceProvider.java:107) at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:191) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79) at org.eclipse.jpt.jpa.eclipselink.core.ddlgen.Main.buildEntityManagerFactory(Main.java:94) at org.eclipse.jpt.jpa.eclipselink.core.ddlgen.Main.execute(Main.java:80) at org.eclipse.jpt.jpa.eclipselink.core.ddlgen.Main.main(Main.java:68)
解决方案
这个错误是因为旧版本EclipseLink解析泛型类型Set<DayOfWeek>时出现BUG,把两个类名直接拼接成了不存在的java.util.Setjava.time.DayOfWeek,可以通过以下方式解决:
方法1:升级EclipseLink版本
使用EclipseLink 2.7.0及以上版本,该版本开始完善支持Java 8的泛型和java.time包API。如果用Maven,修改依赖:
<dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>eclipselink</artifactId> <version>2.7.10</version> <!-- 或更高稳定版本 --> </dependency>
方法2:用自定义包装类替代泛型集合
如果暂时无法升级,创建一个继承自HashSet<DayOfWeek>的具体类,避免泛型解析问题:
import java.time.DayOfWeek; import java.util.HashSet; public class DaysOfWeekSet extends HashSet<DayOfWeek> { // 无需额外代码,继承即可 }
修改实体类字段:
@Column(name="DAYS_BITMAP", length=7) @Convert(converter=DaysOfWeekSetToStringConverter.class) private DaysOfWeekSet daysRunning;
修改转换器的泛型参数:
public class DaysOfWeekSetToStringConverter implements AttributeConverter<DaysOfWeekSet, String> { @Override public String convertToDatabaseColumn(DaysOfWeekSet attribute) { char[] result = "0000000".toCharArray(); for (DayOfWeek dow : attribute) { result[dow.getValue()-1] = '1'; } return new String(result); } @Override public DaysOfWeekSet convertToEntityAttribute(String dbData) { DaysOfWeekSet results = new DaysOfWeekSet(); char[] daysOfWeekMonToSun = dbData.toCharArray(); for (int i=0;i<7;i++) { if (daysOfWeekMonToSun[i] == '1') { results.add(DayOfWeek.of(i+1)); } } return results; } }
方法3:确认基础配置
- 确保项目使用Java 8及以上版本编译运行,
java.time.DayOfWeek是Java 8新增类; - 在
persistence.xml中显式声明实体类和转换器,确保被扫描到:
<persistence-unit name="yourPersistenceUnit"> <!-- 其他配置 --> <class>com.yourpackage.YourEntityClass</class> <class>com.yourpackage.DaysOfWeekSetToStringConverter</class> </persistence-unit>
内容的提问来源于stack exchange,提问作者simonalexander2005
相关产品推荐
相关产品推荐

