我遇到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)
只引起了不同的问题。
知道如何解决这个问题吗?
答案 0 :(得分: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
答案 1 :(得分:0)
这对我来说适合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