2016-12-30 9 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