2013-10-02 44 views
6

我有日期时间性质的实体坚持用休眠如何乔达日期时间转换成JPA本机查询

@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime") 
@Column(name = "EFF_DT") 
protected DateTime effDt; 

这一切运作良好和良好的定期弹簧数据的JPA生成的查询。

我想添加自定义本地查询

@Query(value = "SELECT COUNT(*) FROM wsa_circuit_state_history ch WHERE ch.eff_dt between ?1 and ?2", nativeQuery = true) 
    Integer countEffDateBetween(DateTime start, DateTime end); 

我的错误是,当试图调用这是

java.sql.SQLException: ORA-00932: inconsistent datatypes: expected DATE got BINARY 

这是我用来获取与普通弹簧同样的错误-data finders将自定义类型映射添加到我的实体之前

@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime") 

如何使弹簧-data-jpa/hibernate使用参数的自定义类型映射到本地查询?

+0

你找到这个答案? –

+0

@WojciechGórski不,我没有找到解决办法。最后,我设法在JPA中重新编写查询,然后hibernate @Type注释开始处理来自nz.co.vodafone.wcim的类型转换'@Query(“select count(ch.circuitId)。 model.CircuitStateLog ch其中ch.effDt介于?1和?2之间以及ch.state =?3“)' –

回答

0

你的财产正好被设置为java.util.Date这样

然后在您的getter/setter

public DateTime getEffDt() { 
    return null == effDt ? null : new DateTime(effDt); 
} 

public void setEffDt(final DateTime effDt) { 
    this.effDt = null == effDt ? null : effDt.toDate(); 
} 

原住民转换:

@Query(value = "SELECT COUNT(*) FROM wsa_circuit_state_history ch WHERE ch.eff_dt between ?1 and ?2", nativeQuery = true) 
Integer countEffDateBetween(Date start, Date end); 
+0

这是避免使用DateTime的有趣解决方法,但在我们的情况下,我们希望将该字段保留为DateTime。 –

+0

为什么不能将'countEffDateBetween(DateTime start,DateTime end);'改成'countEffDateBetween(Date start,Date end);'?这将使您能够将您的属性保留为DateTime。 –

+1

我们使用的是DateTime,而不是java.util.Date。当然,如果我们停止使用DateTime并使用Date,我们就不会遇到这个问题。不过,我们希望使用远远优越的joda DateTime API。我的问题是'如何使本机查询与DateTime一起工作',不使用DateTime不是这个问题的解决方案。 –

0

在类似情况下我诉诸写一个自定义的CompositeUserType存储Joda DateTime在两个字段,一个dateti我的领域和时区领域。

当实体保存时,它将时间值存储为UTC,并将时区存储为原始值,在检索时它将做相反的处理(即将存储在数据库中的时间转换回原始时区)。

正如您在上面已经确定的那样,虽然像“datetime BETWEEN?1 AND?2”这样的查询具有直观的意义,当然这对于复合类型来说是没有意义的,因为您需要牢记时区。这是我以UTC存储所有值的原因,所以我总是可以比较数据库上的任何两个日期/时间值。

不幸的是,这意味着我传递的所有日期/时间查询参数必须转换为UTC。

0

准确地说我也得到了相同的要求。我通过注册自定义类型到休眠配置来解决它。

对于本机查询,TypeDefs不足以让hibernate找到用户类型。它需要类型解析器来查找它的类型。

@Query(value = "SELECT COUNT(*) FROM wsa_circuit_state_history ch WHERE ch.eff_dt between ?1 and ?2", nativeQuery = true) 
    Integer countEffDateBetween(DateTime start, DateTime end); 

在这种情况下,hibernate尝试从类型解析器中猜出类型(org.joda.time.DateTime)。

Type type = session.getFactory().getTypeResolver().heuristicType(typename); 

由于没有解析器的DateTime.Then是越来越默认类型(序列化类型)。而日期时间的值被强制转换为它的类型,即序列化和数据库,它是失败的,由于持续以较大的二进制值。

要解决这个问题,你需要注册DateTime类型到Hibernate配置为

configuration.registerTypeOverride(new org.jadira.usertype.dateandtime.joda.PersistentDateTime(), new String[]{"org.joda.time.DateTime"});