假设我要将记录的列值设置为“已解决”。但是,我想从枚举中获取此值。因此,无论有人决定将“ RESOLVED”更改为“ RESOLVE”还是类似的查询,查询都保持不变。换句话说,开发人员无需使用新的Enum值编辑JPA查询。只是想知道有什么解决方法,或者JPA不允许这样做。我知道查询是静态的,但是较早之前,我能够在查询内部传递一个对象以在其中存储查询结果字段。所以我想知道是否也可以对枚举做同样的事情。
这是我目前的策略:将“ RESOLVE”作为@Param“状态”传递。但是,我仍然想知道如何传递枚举,因为这感觉比不回答问题本身更能解决问题。
public interface UpdateStatusStandardDAO extends JpaRepository<DBTableName, Long>
{
@Transactional
@Modifying(clearAutomatically = true)
@Query("UPDATE"
+ " TableName tn"
+ " SET"
+ " tn.status =:status"
+ " WHERE"
+ " tn.field1 =:field1"
+ " AND tn.field2 =:field2"
+ " AND tn.field3 =:field3")
int updateStatus(@Param("status") String status, @Param("field1") Long field1,
@Param("field2") String field2, @Param("field3") String field3);
}
我所知道的: 1. @Transactional:用于更新/删除操作。否则,我得到了org.springframework.dao.InvalidDataAccessApiUsageException。 2. @Modifying(clearAutomatically = true):因为默认情况下,实体管理器不会自动刷新更改。
为简单起见,我们将field1作为主键。它的类型是Long(也可以从接口签名中推断出来)。
对于纯引用,如果where子句中的任何字段都不是键,那么如果设置了SQL_SAFE_UPDATES选项,则SQL工作台可能会拒绝您的查询。这是因为如果不在where子句中指定键(例如主键),就无法更新或删除记录。
答案 0 :(得分:1)
这是不可能的,因为注释属性值必须为常数,而Enum不是常数。但是您可以使用java8接口默认方法作为解决它的技巧。模板代码:
public interface TheEntityJpaRepository extends JpaRepository<TheEntity, Long> {
@Modifying(clearAutomatically = true)
@Query("UPDATE TheEntity SET status = :status WHERE id = :value")
int markToStatus(@Param("value") Long value, @Param("status") TheStatusEnum status);
default int markAsResolved(Long value) {
return markToStatus(value, TheStatusEnum.RESOLVED);
}
}
@Entity
public class YourEntity {
...
@Enumerated(EnumType.STRING)
private Status status;
...
}
public enum TheStatusEnum {
RESOLVED,
...
}
但是您应该知道,这种方式将公开markToStatus
方法。