2016-12-30 27 views
2

我遇到QueryDsl日期算術問題。它不工作對我來說,拋出了以下錯誤:QueryDsl日期算術問題(PostgreSQL背後) - 函數add_minutes(...)不存在

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) 

只引起了不同的問題。

任何想法如何解決這個問題?

回答

0

您必須在方言中註冊該功能。

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