每天都会通过Web服务导入数据。
我知道我可以遍历pojos上的所有字段,并检查null值,并在适当的地方进行更新,但是我更愿意让hibernate做到这一点,因为这样做会减少我添加字段和忘记将其添加到此手动合并过程中。
hibernate状态可以执行上面的步骤4吗?
不,Hibernate(或JPA)没有提供现成的功能,但是使用JavaBeans机制(或在其之上提供抽象层的许多库之一)并不难实现。
这是一种方法,该方法使用标准JavaBeans 机制从中复制所有属性到beanA
,beanB
如果它们为null
:beanB
Introspector
public static void copyBeanProperties(
final Object beanA, final Object beanB){
if(beanA.getClass() != beanB.getClass()){
// actually, this may be a problem, because beanB may be a
// cglib-created subclass
throw new IllegalArgumentException();
}
try{
for( final PropertyDescriptor pd :
Introspector
.getBeanInfo(beanB.getClass(), Object.class)
.getPropertyDescriptors()){
if(pd.getReadMethod().invoke(beanB)==null){
pd.getWriteMethod().invoke(beanB,
pd.getReadMethod().invoke(beanA)
);
}
}
} catch(IntrospectionException e){
throw new IllegalStateException(e);
} catch(IllegalAccessException e){
throw new IllegalStateException(e);
} catch(InvocationTargetException e){
throw new IllegalStateException(e);
}
}
当然,这只是一个快速而肮脏的实现,但这应该可以帮助您入门。
这是一个使用Commons /
BeanUtils的
优雅版本。它隐藏了您的反射,并提供基于地图的属性访问:
public static void copyBeanProperties(final Object beanA, final Object beanB){
try{
@SuppressWarnings("unchecked") // this should be safe
final Map<String, Object> beanAProps = PropertyUtils.describe(beanA);
@SuppressWarnings("unchecked") // this should be safe
final Map<String, Object> beanBProps = PropertyUtils.describe(beanB);
if(!beanAProps.keySet().containsAll(beanBProps.keySet())){
throw new IllegalArgumentException("Incompatible types: "
+ beanA + ", " + beanB);
}
for(final Entry<String, Object> entryA : beanAProps.entrySet()){
if(beanBProps.get(entryA.getKey()) == null){
PropertyUtils.setMappedProperty(beanB, entryA.getKey(),
entryA.getValue());
}
}
} catch(final IllegalAccessException e){
throw new IllegalStateException(e);
} catch(final InvocationTargetException e){
throw new IllegalStateException(e);
} catch(final NoSuchMethodException e){
throw new IllegalStateException(e);
}
}
这是使用Spring
BeanWrapper
接口
的另一个版本(最不冗长,因为Spring在所有反射之上都提供了抽象,并且它是自己的异常处理),但是不幸的BeanWrapper
是,该技术仅适用于Spring
IOC容器(当然,如果您不使用容器):
public static void copyBeanProperties(final Object beanA, final Object beanB){
final BeanWrapper wrapperA = new BeanWrapperImpl(beanA);
final BeanWrapper wrapperB = new BeanWrapperImpl(beanB);
try{
for(final PropertyDescriptor descriptor : wrapperB
.getPropertyDescriptors()){
final String propertyName = descriptor.getName();
if(wrapperB.getPropertyValue(propertyName) == null){
wrapperB.setPropertyValue(propertyName,
wrapperA.getPropertyValue(propertyName));
}
}
} catch(final /* unchecked */ InvalidPropertyException e){
throw new IllegalArgumentException("Incompatible types: " + beanA
+ ", " + beanB, e);
}
}
问题内容: 我试图在spring启动时将JSON对象存储在MySQL数据库中。我知道我做错了事,但是我无法弄清楚到底是什么原因,因为我对Spring还很陌生。 我有一个休息端点,在这里我通过HTTP PUT获取以下JSON对象,并且需要将其存储在数据库中,以便用户以后可以通过HTTP GET获取它。 请注意,在上述情况下,对象 中* 键 的 数量 可能会有所不同,由于该要求,我正在使用a 来捕获控
1. 前言 本节课和大家聊聊持久化对象的 3 种状态。通过本节课程,你将了解到: 持久化对象的 3 种状态; 什么是对象持久化能力。 2. 持久化对象的状态 程序运行期间的数据都是存储在内存中。内存具有临时性。程序结束、计算机挂机…… 内存中的数据将不复存在。 重要的数据,需要使用持久化技术将数据保存到永久性设备上。Hibernate 能够通过 PO(持久化对象) 将数据持久化到数据库。 Hibe
问题内容: 如果设置了FlushMode.AUTO,当我调用session.close()时,Hibernate会刷新我更新的持久对象吗? 我知道session.close()通常不会刷新会话,但是我不确定FlushMode.AUTO如何影响它。 从文档中: FlushMode.AUTO 有时会在执行查询之前刷新会话,以确保查询永远不会返回陈旧状态。这是默认的刷新模式。 这是否意味着我有时可以在会
Hibernate 认为持久化类(persistent class)新实例化的对象是瞬时(Transient)的。我们可通过将瞬时(Transient)对象与 session 关联而把它变为持久的(Persistent)。 DomesticCat fritz = new DomesticCat(); fritz.setColor(Color.GINGER); fritz.setSex('M');
问题内容: 我正在尝试更改持久对象的ID。我在Hibernate和MySQL中使用JPA。我执行代码时遇到的错误是:org.hibernate.HibernateException:com.tutorial.jpa.certification.listing5_18.AA实例的标识符从2更改为99 我找不到此问题的答案,因此在此感谢您的帮助。代码为: 问题答案: 您永远不要修改实体的主键 -这定义
问题内容: 我有POJO类: 然后,我创建一张票证和一些地方: 现在,我想将其保存到数据库: 在MapperConfig.xml中,我这样写: 如何以自动模式保存 列表位置 ?MyBatis可以为我保存吗?还是我需要使用 foreach 手动进行迭代,然后手动插入每个 地方 ? 谢谢你的帮助。 问题答案: 即使MyBatis能够支持相反的方向(即在查询过程中使用嵌套选择或联接填充列表),也没有自动