【问题标题】:QueryDsl date arithmetic issue (PostgreSQL behind) - function add_minutes(...) does not existQueryDsl 日期算术问题(PostgreSQL 落后)- 函数 add_minutes(...) 不存在
【发布时间】:2017-05-15 01:03:37
【问题描述】:

我遇到了 QueryDsl 日期算术问题。它对我不起作用,引发以下错误:

Caused by: org.postgresql.util.PSQLException: ERROR: function add_minutes(timestamp with time zone, integer) does not exist

我使用的是PostgreSQL数据库,版本如下:

PostgreSQL 9.4.4 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu 4.9.2-10ubuntu13) 4.9.2, 64-bit

QueryDsl 版本为:3.7.4

这是查询代码:

import static com.experthub.ws.model.QExpertAppointmentStatusChangeEntity.expertAppointmentStatusChangeEntity;
import static com.mysema.query.support.Expressions.dateTimeOperation;
import static com.mysema.query.types.expr.BooleanExpression.allOf;

public class ExpertAppointmentRepositoryImpl implements ExpertAppointmentRepositoryCustom {

    private EntityManager entityManager;

    @Autowired
    public ExpertAppointmentRepositoryImpl(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public Integer getNumPendingAppointments(Integer userId, Date currentTime) {
        return (int) new JPAQuery(entityManager)
                .from(expertAppointmentStatusChangeEntity)
                .where(
                        allOf(
                                expertAppointmentStatusChangeEntity.expertAppointmentEntity().userExpertEntity().id.eq(userId),
                                dateTimeOperation(
                                        Date.class,
                                        Ops.DateTimeOps.ADD_MINUTES,
                                        expertAppointmentStatusChangeEntity.expertAppointmentEntity().appointmentTime,
                                        expertAppointmentStatusChangeEntity.expertAppointmentEntity().duration).after(currentTime)))
                .count();
    }

这就是实体的样子:

@Entity
@Table(name = "expert_appointment_status_change")
@EqualsAndHashCode(of = "id")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ExpertAppointmentStatusChangeEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    @ManyToOne
    @JoinColumn(name = "id_expert_appointment", nullable = false)
    private ExpertAppointmentEntity expertAppointmentEntity;

    @Column(name = "status", nullable = false)
    private Integer status;

    @Column(name = "change_time", nullable = false)
    private Date changeTime;

    @Column(name = "change_initiator", nullable = false)
    private Integer changeInitiator;

    @Column(name = "message", length = 512)
    private String message;
}
@Entity
@Table(name = "expert_appointment")
@EqualsAndHashCode(of = "id")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ExpertAppointmentEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    @ManyToOne
    @JoinColumn(name = "id_user", nullable = false)
    private UserEntity userEntity;

    @ManyToOne
    @JoinColumn(name = "id_user_expert", nullable = false)
    private UserEntity userExpertEntity;

    @Column(name = "appointment_time", nullable = false)
    private Date appointmentTime;

    @Column(name = "duration", nullable = false)
    private Integer duration;

    // some other fields

    @OneToMany(mappedBy = "expertAppointmentEntity")
    @OrderBy("changeTime DESC")
    private List<ExpertAppointmentStatusChangeEntity> expertAppointmentStatusChangeEntities;
}

我还没有找到任何其他方法来做这个算术。

我知道this class 的存在,但不确定如何将它集成到我的代码中。

也在尝试这样做:

public class PostgreSQLJPQLTemplates extends JPQLTemplates {

    public PostgreSQLJPQLTemplates() {
        super();

        add(Ops.DateTimeOps.ADD_YEARS, "{0} + interval '{1s} years'");
        add(Ops.DateTimeOps.ADD_MONTHS, "{0} + interval '{1s} months'");
        add(Ops.DateTimeOps.ADD_WEEKS, "{0} + interval '{1s} weeks'");
        add(Ops.DateTimeOps.ADD_DAYS, "{0} + interval '{1s} days'");
        add(Ops.DateTimeOps.ADD_HOURS, "{0} + interval '{1s} hours'");
        add(Ops.DateTimeOps.ADD_MINUTES, "{0} + interval '{1s} minutes'");
        add(Ops.DateTimeOps.ADD_SECONDS, "{0} + interval '{1s} seconds'");
    }
}

并将其作为第二个参数添加到 JPAQuery 构造函数:

// somwhere in code
PostgreSQLJPQLTemplates template = new PostgreSQLJPQLTemplates();

new JPAQuery(entityManager, template)

只是导致了不同的问题。

知道如何解决这个问题吗?

【问题讨论】:

    标签: java spring postgresql jpql querydsl


    【解决方案1】:

    您必须在方言中注册该功能。

    public class BimDB2Dialect extends DB2Dialect {
    
    public BimDB2Dialect() {
        registerFunction("add_years", new SQLFunctionTemplate(StandardBasicTypes.DATE, "?1 + ?2 years"));
        registerFunction("add_months", new SQLFunctionTemplate(StandardBasicTypes.DATE, "?1 + ?2 months"));
        registerFunction("add_weeks", new SQLFunctionTemplate(StandardBasicTypes.DATE, "?1 + 7 * ?2 days"));
        registerFunction("add_days", new SQLFunctionTemplate(StandardBasicTypes.DATE, "?1 + ?2 days"));
    
    }
    

    }

    查看帖子Date arithemtic

    【讨论】:

    • 对于使用 MariaDB 的人:我必须像这样注册函数:registerFunction("add_years", new SQLFunctionTemplate(StandardBasicTypes.DATE, "DATE_ADD(?1, INTERVAL ?2 YEAR)"));
    【解决方案2】:

    这对我来说适用于 postgres。

    public class CustomPostgreSQL9Dialect extends PostgreSQL95Dialect{
    
        public CustomPostgreSQL9Dialect() {
            super();
            registerFunction("add_years", new SQLFunctionTemplate(StandardBasicTypes.DATE, "?1 + interval '1 years' * ?2"));
            registerFunction("add_months", new SQLFunctionTemplate(StandardBasicTypes.DATE, "?1 + interval '1 months' * ?2"));
            registerFunction("add_weeks", new SQLFunctionTemplate(StandardBasicTypes.DATE, "?1 + interval '1 days' * 7 * ?2"));
            registerFunction("add_days", new SQLFunctionTemplate(StandardBasicTypes.DATE, "?1 + interval '1 days' * ?2"));
            registerFunction("add_minutes", new SQLFunctionTemplate(StandardBasicTypes.DATE, "?1 + interval '1 minutes' * ?2"));
        }
    }
    

    设置休眠方言

    hibernate.dialect=<package>.CustomPostgreSQL9Dialect
    

    【讨论】:

    • 你是如何在 hql 中使用 add_days 的?
    猜你喜欢
    • 1970-01-01
    • 2018-04-03
    • 1970-01-01
    • 2012-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    • 2012-11-28
    相关资源
    最近更新 更多