情况 :
我有一个具有java.util.Date类型变量的可持久类:
import java.util.Date;
@Entity
@Table(name = "prd_period")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Period extends ManagedEntity implements Interval {
@Column(name = "startdate_", nullable = false)
private Date startDate;
}
DB中的对应表:
CREATE TABLE 'prd_period' ( 'id_' bigint(20) NOT NULL AUTO_INCREMENT, ... 'startdate_' datetime NOT NULL )
然后,将我的Period对象保存到DB:
Period p = new Period();
Date d = new Date();
p.setStartDate();
myDao.save(p);
之后,如果我尝试从数据库中提取对象,则使用时间戳记类型的变量startDate返回该对象-我尝试使用equals(…)的所有位置均返回false。
问题
:是否有任何方法可以强制Hibernate以java.util.Date类型的对象(而不是Timestamp)的形式返回日期,而无需显式修改每个此类变量(例如,它必须能够正常工作,而无需显式修改java.util的现有变量日期类型)?
注意:
我发现了许多显式解决方案,其中使用了批注或修改了setter,但是我有很多带有Date-variables的类-
因此,我需要一些集中式解决方案,而下面描述的所有内容还不够好:
@Column
@Type(type="date")
private Date startDate;
@Temporal(TemporalType.DATE)
@Column(name=”CREATION_DATE”)
private Date startDate;
public void setStartDate(Date startDate) {
if (startDate != null) {
this.startDate = new Date(startDate.getTime());
} else {
this.startDate = null;
}
}
此处提供了详细信息:http : //blogs.sourceallies.com/2012/02/hibernate-date-vs-
timestamp/
因此,我花了一些时间解决这个问题,并找到了解决方案。它不是一个漂亮的东西,但至少是一个起点-也许有人会用一些有用的注释来补充它。
我在处理中发现的一些有关映射的信息:
private static final Map BASIC_TYPES;
...
basics.put( java.util.Date.class.getName(), Hibernate.TIMESTAMP );
...
BASIC_TYPES = Collections.unmodifiableMap( basics );
如您所见,java.util.Date类型与Hibernate类型org.hibernate.type.TimestampType相关联
Iterator clsMappings = cfg.getClassMappings();
while(clsMappings.hasNext()){
PersistentClass mapping = (PersistentClass) clsMappings.next();
handleProperties(mapping.getPropertyIterator(), map);
}
Type result = TypeFactory.heuristicType(typeName, typeParameters);
至此,我了解到我无法修改BASIC_TYPES(这是唯一的方法),无法将SimpleValue对象替换为java.util.Date类型的属性,更改为我的自定义对象,从而可以知道要转换的确切类型。
解决方案:
public class HibernatePersistenceExtensions extends HibernatePersistence {
@Override
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map map) {
if ("true".equals(map.get("hibernate.use.custom.entity.manager.factory"))) {
return CustomeEntityManagerFactoryFactory.createCustomEntityManagerFactory(info, map);
} else {
return super.createContainerEntityManagerFactory(info, map);
}
}
}
public class ReattachingEntityManagerFactoryFactory {
@SuppressWarnings("rawtypes")
public static EntityManagerFactory createContainerEntityManagerFactory(
PersistenceUnitInfo info, Map map) {
Ejb3Configuration cfg = new Ejb3Configuration();
Ejb3Configuration configured = cfg.configure( info, map );
handleClassMappings(cfg, map);
return configured != null ? configured.buildEntityManagerFactory() : null;
}
@SuppressWarnings("rawtypes")
private static void handleClassMappings(Ejb3Configuration cfg, Map map) {
Iterator clsMappings = cfg.getClassMappings();
while(clsMappings.hasNext()){
PersistentClass mapping = (PersistentClass) clsMappings.next();
handleProperties(mapping.getPropertyIterator(), map);
}
}
private static void handleProperties(Iterator props, Map map) {
while(props.hasNext()){
Property prop = (Property) props.next();
Value value = prop.getValue();
if (value instanceof Component) {
Component c = (Component) value;
handleProperties(c.getPropertyIterator(), map);
} else {
handleReturnUtilDateInsteadOfTimestamp(prop, map);
}
}
private static void handleReturnUtilDateInsteadOfTimestamp(Property prop, Map map) {
if ("true".equals(map.get("hibernate.return.date.instead.of.timestamp"))) {
Value value = prop.getValue();
if (value instanceof SimpleValue) {
SimpleValue simpleValue = (SimpleValue) value;
String typeName = simpleValue.getTypeName();
if ("java.util.Date".equals(typeName)) {
UtilDateSimpleValue udsv = new UtilDateSimpleValue(simpleValue);
prop.setValue(udsv);
}
}
}
}
}
如您所见,我只是遍历每个属性,并用SimpleValue-object替换UtilDateSimpleValue来替换类型java.util.Date的属性。这是一个非常简单的类-它实现与SimpleValue对象相同的接口,例如org.hibernate.mapping.KeyValue。在构造函数中,将传递原始SimpleValue对象-
因此,每次调用UtilDateSimpleValue都会被重定向到原始对象,但有一个异常-方法getType(…)返回我的自定义类型。
public class UtilDateSimpleValue implements KeyValue{
private SimpleValue value;
public UtilDateSimpleValue(SimpleValue value) {
this.value = value;
}
public SimpleValue getValue() {
return value;
}
@Override
public int getColumnSpan() {
return value.getColumnSpan();
}
...
@Override
public Type getType() throws MappingException {
final String typeName = value.getTypeName();
if (typeName == null) {
throw new MappingException("No type name");
}
Type result = new UtilDateUserType();
return result;
}
...
}
public class UtilDateUserType extends TimestampType{
@Override
public Object get(ResultSet rs, String name) throws SQLException {
Timestamp ts = rs.getTimestamp(name);
Date result = null;
if(ts != null){
result = new Date(ts.getTime());
}
return result;
}
}
就这些。有点棘手,但是现在每个java.util.Date属性都作为java.util.Date返回,而无需对现有代码进行任何其他修改(注释或修改setter)。
问题内容: 我正在使用Oracle 11GR2,并且当varchar2字段为空时,在空字段上执行a 将显示在我的Eclipse控制台上。如何让它显示空字符串呢? 问题答案: 你的getter方法:
问题内容: 这是我的发件人实体 当我尝试执行以下查询时: 发生以下错误: 错误:org.hibernate.property.BasicPropertyAccessor- HHH000123:类中的IllegalArgumentException:be.gimme.persistence.entities.Sender,属性的设置方法:senderId 错误:org.hibernate.prope
当我使用Guzzle发送请求时,它会返回一条完整的错误消息,而不会解析内部的JSON。下面是它的外观: “”“ 客户端错误: 导致 响应:\n {\r\n ”错误“: [\r\n ”潜在客户已在此市场活动中“\r\n ]\r\n }\n ”“” 当我通过Postman发送相同的请求时,它确实会返回正确解析的响应消息。 我如何才能让Guzzle只返回消息,而不是完整的响应?
Edit:不幸的是,我需要以日期的形式获得结果,而不是字符串,所以我不能使用sdf.format(New Date().getTime()),因为它返回字符串。另外,我需要返回的日期是当前时间的日期,而不是来自静态字符串。我希望这能澄清
问题内容: 输出: IST 2017年9月12日12:36:24 IST 2007年1月1日星期一12:36:24 但是,当我在不同的环境中使用相同的代码时,输出更改为以下内容: 输出: IST 2017年9月12日12:36:24 2007年1月1日星期一格林尼治标准时间12:36:24 仅供参考,我尝试在设置值之前和之后打印日历实例的时区,并且两者都在“ IST”中。 我想知道这个的根本原
问题内容: 我正在为我的Web应用程序使用Hibernate和Spring。 在数据库操作中,Hibernate正在缓存实体并在下一个请求中返回它们,而不读取实际的数据库。我知道这将减少数据库的负载并提高性能。 但是,尽管此应用仍在构建中,但我需要在每个请求中从数据库加载数据(测试原因)。 有什么办法可以强制数据库读取? 我确定从此log4j消息进行缓存。 问题答案: 或(如果您使用JPA)将为您