【问题标题】:How to use DayOfWeek with Spring, JPA and PostgreSQL?如何在 Spring、JPA 和 PostgreSQL 中使用 DayOfWeek?
【发布时间】:2020-02-28 00:03:01
【问题描述】:

我想在我的 PostgreSQL 数据库中存储 DayOfWeek。因此我使用转换器将其存储为整数。但如果您有更好的建议,我愿意将其存储为其他数据类型。 转换不会发生,因为我没有看到我添加的错误打印。错误消息加强了这一点。 我是否必须更改我的 crudrepository 或我的错误在哪里? 我的实体是:

@Entity
@Table(name = "opening_hours")
public class OpeningHours {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", updatable = false, nullable = false)
    private Long id;

    @Column(name = "day")
    @Convert(converter = DayOfWeekIntegerConverter.class)
    private DayOfWeek day;


我使用的 CrudRepository 看起来像这样:

public interface OpeningHoursRepository extends CrudRepository<OpeningHours, Long> {

    @Query(value = "SELECT closing_time FROM opening_hours WHERE day = :day_of_week", nativeQuery = true)
    LocalTime getShopClosingTimeOn(@Param("day_of_week") DayOfWeek dayOfWeek);

为了存储 DayOfWeek,我使用以下转换器:

@Converter // I tried (autoapply=true) already but did not change anything
public class DayOfWeekIntegerConverter implements AttributeConverter<DayOfWeek, Integer> {
    @Override
    public Integer convertToDatabaseColumn(DayOfWeek attribute) {
        System.err.println("converting dayofweek to int");
        return attribute.getValue();
    }

    @Override
    public DayOfWeek convertToEntityAttribute(Integer dbData) {
        System.err.println("converting int to dayofweek ");
        return DayOfWeek.of(dbData);
    }
}

我的数据库表如下所示:

CREATE TABLE IF NOT EXISTS opening_hours
(
    id BIGSERIAL NOT NULL PRIMARY KEY,
    day INT
);

这是错误:

org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause
...
org.postgresql.util.PSQLException: ERROR: operator does not exist: integer = bytea
  Hinweis: No operator matches the given name and argument types. You might need to add explicit type casts.
  Position: 51

【问题讨论】:

  • 您能否向我们提供一条错误消息或其他向我们展示您遇到的问题的信息?
  • 添加了错误信息。将其保存为日期是没有选择的,因为我只对一周中的哪一天感兴趣。不想处理任何特定日期
  • 修改了我的答案@juuubbb
  • 你在修改后的答案中尝试过我的建议吗

标签: java spring postgresql jpa


【解决方案1】:

您的转换器没有问题。 主要问题是您对存储库的查询。我已经在我的本地环境中更改了它,它就像一个魅力。

我在原生查询中使用了 JQL

下面是我的代码

public interface OpeningHoursRepository extends CrudRepository<OpeningHours, Long> {

    @Query(value = "SELECT closingTime FROM OpeningHours WHERE day = :day_of_week")
    public LocalTime getShopClosingTimeOn(@Param("day_of_week") DayOfWeek dayOfWeek);

}

我假设了一个变量 closureTime 因为您在帖子中的代码没有它

public class OpeningHours {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", updatable = false, nullable = false)
    private Long id;


    private LocalTime closingTime;

    @Column(name = "day")
    @Convert(converter = DayOfWeekIntegerConverter.class)
    private DayOfWeek day;
}

编辑:

如果你想坚持原生查询

那么你应该如下编写你的存储库

public interface OpeningHoursRepository extends CrudRepository<OpeningHours, Long> {

@Query(value = "SELECT closing_time FROM opening_hours WHERE day = :#{#day_of_week.getValue()}", nativeQuery = true)
    public LocalTime getShopClosingTimeOn(@Param("day_of_week") DayOfWeek dayOfWeek);

     }

【讨论】:

  • nextval('shaileshtest.opening_hours_id_seq'::regclass) 这是什么?我认为更大的问题是转换不起作用
  • 根据讨论修改了答案
  • 很高兴知道:),如果它对你有用,请接受@juuubbb
  • 对不起,我现在这样做了。 Upvoting 不起作用,因为我的帐户相对较新。这个#{# 背后的语法到底是什么?
  • 不用担心投票,一个接受的答案就足够了,因为它增加了答案的可信度
【解决方案2】:

Converter 类在 Entity 中工作,因为 @Convert 注释,但在存储库中,JPA 无法将 DayOfWeek 参数转换为本地查询中的整数。

更好的解决方案是编写 JPQL 查询,这样 JPA 将使用 OpeningHours 类,它会看到 DayOfWeek 参数与 day 属性匹配,它会进行转换。

【讨论】:

  • 所以对于您的解决方案,我只需要删除“nativeQuery = true”?因为这会导致异常,即未映射表 opening_hours.. java.lang.IllegalArgumentException: Validation failed for query for method public abstract java.time.LocalTime backend.dataaccess.OpeningHoursRepository.getShopClosingTimeOn(java.time.DayOfWeek)! ... java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: opening_hours is not mapped [SELECT closing_time FROM opening_hours WHERE day = :day_of_week]
  • 我已经测试了你的代码,如果你想要最小的变化,要么将存储库中的 dayofwek 更改为整数,要么将查询更改为 day = :#{#day_of_week.getValue()}"
  • 这是有效的,非常感谢@ShaileshChandra
猜你喜欢
  • 2018-06-02
  • 2021-09-02
  • 2021-06-07
  • 1970-01-01
  • 2017-06-07
  • 2018-01-03
  • 1970-01-01
  • 1970-01-01
  • 2016-06-26
相关资源
最近更新 更多