Hibernate自定义类型和JPA2标准查询
我们在尝试将CriteriaBuilder用于自定义类型字段时遇到了一个问题 下面的示例显示了用自定义@Type注释的生日字段Hibernate自定义类型和JPA2标准查询,hibernate,jpa,jboss7.x,Hibernate,Jpa,Jboss7.x,我们在尝试将CriteriaBuilder用于自定义类型字段时遇到了一个问题 下面的示例显示了用自定义@Type注释的生日字段 @Entity @Table(name = "People") public class People { @Id @NotNull @Column(name = "id") private Integer id; @NotNull @Size(min = 1, max = 20) @Column(name = "Name") priv
@Entity
@Table(name = "People")
public class People {
@Id
@NotNull
@Column(name = "id")
private Integer id;
@NotNull
@Size(min = 1, max = 20)
@Column(name = "Name")
private String name;
@NotNull
@Column(name = "Birthdate")
@Type(type = "test.MyDateType")
@Temporal(TemporalType.TIMESTAMP)
private MyDate birthdate;
...
}
MyDateType实现hibernate的EnhancedUserType
package test;
import java.io.Serializable;
import java.sql.*;
import java.text.*;
import java.util.*;
import java.util.Date;
import org.hibernate.HibernateException;
import org.hibernate.usertype.EnhancedUserType;
import org.hibernate.engine.spi.SessionImplementor;
public class MyDateType implements EnhancedUserType {
static final ThreadLocal<Calendar> utcCalendar = new ThreadLocal<Calendar>() {
@Override
protected Calendar initialValue() {
return Calendar.getInstance(TimeZone.getTimeZone("GMT"));
}
};
static final ThreadLocal<SimpleDateFormat> utcSimpleDateFormat = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
df.setTimeZone(TimeZone.getTimeZone("GMT"));
return df;
}
};
private static final int[] SQL_TYPES = {Types.TIMESTAMP};
@Override
public int[] sqlTypes() {
return SQL_TYPES;
}
@Override
public boolean equals(Object o1, Object o2) {
if(o1 == o2) {
return true;
}
if((o1 == null) || (o2 == null)) {
return false;
}
return o1.equals(o2);
}
@Override
public boolean isMutable() {
return true;
}
@Override
public Class<?> returnedClass() {
return objectClass;
}
protected Class<?> objectClass = MyDate.class;
@Override
public Object deepCopy(Object value) {
return (value == null) ? null : new MyDate(((Date)value).getTime());
}
@Override
public Object nullSafeGet(ResultSet rs, String[] columns, SessionImplementor si, Object owner) throws HibernateException, SQLException {
Timestamp ts = rs.getTimestamp(columns[0], utcCalendar.get());
if(ts != null) {
return new Date(ts.getTime());
}
return null;
}
@Override
public void nullSafeSet(PreparedStatement statement, Object value, int index, SessionImplementor si) throws HibernateException,
SQLException {
Object val = value;
if(!(val instanceof java.sql.Timestamp)) {
val = (val == null) ? null : new java.sql.Timestamp(((Date)val).getTime());
}
statement.setTimestamp(index, (java.sql.Timestamp)val, utcCalendar.get());
}
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return deepCopy(cached);
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable)deepCopy(value);
}
@Override
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return deepCopy(original);
}
@Override
public Object fromXMLString(String xmlValue) {
try {
return new Date(utcSimpleDateFormat.get().parse(xmlValue).getTime());
} catch(ParseException e) {
System.out.println(e);
}
return xmlValue;
}
@Override
public String objectToSQLString(Object value) {
return null;
}
@Override
public String toXMLString(Object value) {
return value.toString();
}
}
我们知道注释是有效的,因为当我们查询Id时,我们会为birthdate字段返回正确的数据。
当我们构建以下查询时,它也可以正常工作
MyDate start = new MyDate(...);
MyDate end = new MyDate(...):
TypedQuery<People> q = entityManager.createQuery("select p from people where birthdate >= :start and birthdate <= :end", People.class);
q.setParameter("start", start);
q.setParameter("end", end);
List<People> results = q.getResultList();
MyDate start=newmydate(…);
MyDate end=新的MyDate(…):
TypedQuery q=entityManager.createQuery(“从出生日期>=:开始和出生日期的人中选择p,请添加test.MyDateType
我已经在上面包含了MyDataType
22:03:44,733 WARN [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-/0.0.0.0:8080-1) SQL Error: 210, SQLState: S0001
22:03:44,734 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (http-/0.0.0.0:8080-1) Conversion failed when converting datetime from binary/varbinary string.
MyDate start = new MyDate(...);
MyDate end = new MyDate(...):
TypedQuery<People> q = entityManager.createQuery("select p from people where birthdate >= :start and birthdate <= :end", People.class);
q.setParameter("start", start);
q.setParameter("end", end);
List<People> results = q.getResultList();