JPA-JPQL构造函数表达式处理枚举类型时抛出InvalidDataAccessApiUsageException
Spring Data JPA自定义枚举查询异常解决
问题现象
执行JPQL查询时抛出异常:
org.springframework.dao.InvalidDataAccessApiUsageException: Could not determine appropriate instantiation strategy - no matching constructor found and one or more arguments did not define alias for bean-injection
相关代码如下:
JPQL查询方法
@Query("select new DateDto(dayOfWeek) from Dates") Set<DateDto> findAllDaysOfWeek();
DTO记录类
public record DateDto(DayOfWeek dayOfWeek) {}
自定义枚举类
public enum DayOfWeek { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY; }
解决方法
1. 明确JPQL中的字段引用
给表添加别名,显式指定枚举字段,避免JPA解析时出现歧义:
@Query("select new DateDto(d.dayOfWeek) from Dates d") Set<DateDto> findAllDaysOfWeek();
2. 确认实体类字段类型匹配
检查Dates实体中的dayOfWeek字段类型必须是自定义的DayOfWeek枚举,不能是java.time.DayOfWeek或其他类型,确保类型完全一致。
3. 添加枚举类型转换器(按需)
如果数据库存储的是枚举的字符串/数值,需要添加转换器实现枚举与数据库字段的双向映射:
import jakarta.persistence.AttributeConverter; import jakarta.persistence.Converter; @Converter(autoApply = true) public class DayOfWeekConverter implements AttributeConverter<DayOfWeek, String> { @Override public String convertToDatabaseColumn(DayOfWeek dayOfWeek) { return dayOfWeek.name(); } @Override public DayOfWeek convertToEntityAttribute(String dbData) { return DayOfWeek.valueOf(dbData); } }
若未设置autoApply=true,需在实体类的dayOfWeek字段上添加@Convert(converter = DayOfWeekConverter.class)注解。
4. 开启编译时参数名保留
确保JPA能通过参数名匹配record的构造参数,在Maven/Gradle中开启-parameters编译选项:
Maven配置示例:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <parameters>true</parameters> <source>17</source> <!-- 替换为你的Java版本 --> <target>17</target> </configuration> </plugin> </plugins> </build>
内容的提问来源于stack exchange,提问作者planktonchumbucket
相关产品推荐
相关产品推荐

