【问题标题】:Spring Data Repository ignores Hibernate's @ConvertSpring Data Repository 忽略 Hibernate 的 @Convert
【发布时间】:2018-09-05 09:00:05
【问题描述】:

我有以下原生查询:

@Transactional
@Query(nativeQuery = true, value =
        "INSERT INTO my_entity (update_date_time) " +
        "VALUES (:#{#e.getUpdateDateTime()}) " +
        "ON CONFLICT (hash) DO NOTHING RETURNING *")
Long insert(MyEnitity e);

这里是映射:

@Entity
@Table(name = "my_entity")
public class MyEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Access(AccessType.PROPERTY)
    private Long id;    
    @Column(name = "update_date_time")
    @Convert(converter = LocalDateTimeAttributeConverter.class)
    private LocalDateTime updateDateTime;
....
}

如果我调用 Repository.save(MyEntity),它会起作用。但是由于某种原因,当调用此查询时,spring 数据会忽略 @Convert 注释,并且不会为字段 updateDateTime 调用转换器,尽管它在后台使用休眠查询。我猜是因为它是本机查询,而休眠只知道 db 列而不知道实体字段。在执行本机查询时如何告诉 spring 和 hibernate 使用我的转换器的任何想法。

【问题讨论】:

  • 当然它会忽略它。您正在执行一个完全绕过 JPA 类型系统的原生 SQL 查询。
  • 我明白了,有什么办法可以管理这种行为吗?

标签: java spring hibernate spring-data-jpa


【解决方案1】:

我应用了以下解决方法。我已经为我添加了所需的函数来弹簧评估上下文,如下所示:

@Component
public class CustomEvaluationContextExtension extends EvaluationContextExtensionSupport {

    private static final Map<String, Function> functions = new HashMap<>();

    static {
        functions.put("ldt2timestamp", createLdt2timestampFunc());
    }

    private static Function createLdt2timestampFunc() {
        Method convertToDatabaseColumn =
                ReflectionUtils.findMethod(LocalDateTimeAttributeConverter.class,
                        "convertToDatabaseColumn", LocalDateTime.class);

        return new Function(convertToDatabaseColumn,
                LocalDateTimeAttributeConverter.INSTANCE);
    }

    @Override
    public Map<String, Function> getFunctions() {
        return functions;
    }

    @Override
    public String getExtensionId() {
        return "custom";
    }

}

在我的查询中以以下方式调用 ldt2timestamp 后:

@Transactional
@Query(nativeQuery = true, value =
        "INSERT INTO my_entity (update_date_time) " +
        "VALUES (:#{#root.ldt2timestamp(#e.getUpdateDateTime())}) " +
        "ON CONFLICT (hash) DO NOTHING RETURNING *")
Long insert(MyEntity e);

它对我有用。希望这会对某人有所帮助。

【讨论】:

    猜你喜欢
    • 2021-06-01
    • 1970-01-01
    • 2020-03-12
    • 2015-11-13
    • 2022-08-15
    • 1970-01-01
    • 2016-07-19
    • 2019-07-02
    • 2015-08-03
    相关资源
    最近更新 更多