【发布时间】:2023-03-10 04:59:01
【问题描述】:
我有一个自定义 UserType,它在 TIMESTAMP 字段中存储日期/时间值,并在插入或更新记录时更新为“UTC”中的当前时间。 (此字段不用于版本控制或 id 目的。)
问题是这很好用,但是如果您需要在构建准备好的语句时运行此字段是条件之一的查询,则调用自定义用户类型 nullSafeSet 将值设置为当前时间,因此查询总是将该条件设置为当前时间,这不会产生所需的结果。
可以让 nullSafeSet 知道它被调用的上下文,以便它可以调整它的行为以进行插入/更新或选择。或者也许还有其他方法可以做到这一点?
我尝试过使用
是否仍然可以让自定义用户类型以 UTC 格式写入值,但使用某种生成器仅在插入和更新时获取当前日期/时间?
包装示例; 导入 java.io.Serializable; 导入 java.sql.PreparedStatement; 导入java.sql.ResultSet; 导入java.sql.SQLException; 导入java.sql.Timestamp; 导入 java.util.Calendar; 导入 java.util.Date; 导入 java.util.GregorianCalendar; 导入 java.util.Properties; 导入 java.util.TimeZone; 导入 org.hibernate.HibernateException; 导入 org.hibernate.usertype.ParameterizedType; 导入 org.hibernate.usertype.UserType; /** *DateTimestampUserType 类实现了一个 Hibernate
* UserType 允许Date
* instances as a TIMESTAMP in the database.
*
* All Date instances persisted are in UTC/GMT time.
*
* This UserType implementation also allows for a boolean parameter
* 'updateToNow' specified as part of Hibernate configuration. This parameter
* controls whether when a Date 的持久化需要持久化它已更新
* 到当前时间。这对于像 TimeModified 这样的字段很有用
* 不需要调用代码的干预。
*/
公共类 DateTimestampUserType 实现 UserType,ParameterizedType {
/* 常量 */
私有静态最终字符串 UTC_TZ = "GMT";
/* 成员变量 */
私有布尔 m_updateToNow = false;
/* 方法 */
/* (非 Javadoc)
* @see org.hibernate.usertype.ParameterizedType#setParameterValues(java.util.Properties)
*/
公共无效 setParameterValues(属性参数){
if (parameters != null && parameters.containsKey("updateToNow")) {
m_updateToNow = Boolean.parseBoolean(parameters.getProperty("updateToNow"));
}
}
/* (非 Javadoc)
* @see org.hibernate.usertype.UserType#assemble(java.io.Serializable, java.lang.Object)
*/
公共对象组装(可序列化缓存,对象所有者)抛出 HibernateException {
返回缓存;
}
/* (非 Javadoc)
* @see org.hibernate.usertype.UserType#deepCopy(java.lang.Object)
*/
公共对象 deepCopy(对象对象)抛出 HibernateException {
如果(对象==空)返回空;
返回新日期(((日期)对象).getTime());
}
/* (非 Javadoc)
* @see org.hibernate.usertype.UserType#disassemble(java.lang.Object)
*/
公共可序列化反汇编(对象值)抛出 HibernateException {
返回(可序列化)值;
}
/* (非 Javadoc)
* @see org.hibernate.usertype.UserType#equals(java.lang.Object, java.lang.Object)
*/
公共布尔等于(对象 x,对象 y)抛出 HibernateException {
如果 (x == y) 返回真;
if (x == null || y == null) 返回假;
返回 x.equals(y);
}
/* (非 Javadoc)
* @see org.hibernate.usertype.UserType#hashCode(java.lang.Object)
*/
公共 int hashCode(Object object) 抛出 HibernateException {
返回对象.hashCode();
}
/* (非 Javadoc)
* @see org.hibernate.usertype.UserType#isMutable()
*/
公共布尔 isMutable() {
返回真;
}
/* (非 Javadoc)
* @see org.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet, java.lang.String[], java.lang.Object)
*/
public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException, SQLException {
日期结果 = null;
日历 cal = new GregorianCalendar(TimeZone.getTimeZone(UTC_TZ));
时间戳timeStamp = resultSet.getTimestamp(names[0], cal);
结果 = 新日期(timeStamp.getTime());
返回结果;
}
/* (非 Javadoc)
* @see org.hibernate.usertype.UserType#nullSafeSet(java.sql.PreparedStatement, java.lang.Object, int)
*/
public void nullSafeSet(PreparedStatement statement, Object value, int index) throws HibernateException, SQLException {
如果(m_updateToNow){
值 = 新日期();
}
日历 cal = new GregorianCalendar(TimeZone.getTimeZone(UTC_TZ));
时间戳 x = new Timestamp(((Date)value).getTime());
statement.setTimestamp(index, x, cal);
}
/* (非 Javadoc)
* @see org.hibernate.usertype.UserType#replace(java.lang.Object, java.lang.Object, java.lang.Object)
*/
公共对象替换(对象原始,对象目标,对象所有者)抛出 HibernateException {
如果(m_updateToNow){
返回新日期();
} 别的 {
退回原件;
}
}
/* (非 Javadoc)
* @see org.hibernate.usertype.UserType#returnedClass()
*/
公共类返回类(){
返回日期.class;
}
/* (非 Javadoc)
* @see org.hibernate.usertype.UserType#sqlTypes()
*/
公共 int[] sqlTypes() {
返回新的 int[] { java.sql.Types.TIMESTAMP };
}
}
【问题讨论】: