java/Spring Hibernate不更新实体
我已经在SO和许多其他网站上反复阅读了这里的所有内容,但似乎不明白为什么我更新的对象没有更新 我所做工作的基本概述:java/Spring Hibernate不更新实体,java,spring,hibernate,jpa,persistence,Java,Spring,Hibernate,Jpa,Persistence,我已经在SO和许多其他网站上反复阅读了这里的所有内容,但似乎不明白为什么我更新的对象没有更新 我所做工作的基本概述: 服务层为一些人请求DAO 从数据库(DAO/@Repository)返回人员的ArrayList 服务层操纵对象并将其添加到新的arraylist中 服务层将新列表传递回DAO进行更新 未更新任何内容 如果我在我的对象中抛出一条日志消息,并且该对象具有新的值,则表示孩子们已正确补水。代码中没有错误,只是没有提交更改 下面是一些代码: PersonDAO注释为@Repository
/*字段+getter和setter*/
@OneToMany(fetch=FetchType.LAZY,mappedBy=“store”,cascade={CascadeType.MERGE,CascadeType.PERSIST})
@LazyCollection(LazyCollectionOption.EXTRA)
@杰索尼奥雷
公共集合getPersons(){
将本文件归还给所有人;
}
EDIT我在上面添加了两组级联类型注释,但仍然没有成功
编辑2更新以显示主键定义
在我踢小狗之前,请有人帮帮我。
谢谢在这种情况下,您可能需要在manytone注释上设置“cascade={CascadeType.MERGE,CascadeType.PERSIST}”。默认行为不会将任何内容级联到关联对象
/**
* (Optional) The operations that must be cascaded to
* the target of the association.
*
* <p> By default no operations are cascaded.
*/
CascadeType[] cascade() default {};
更新:
如果您使用的是spring托管事务管理器,并且可以自由使用注释驱动的事务划分,那么您可以尝试spring@Transactional注释,而不是手动启动事务和提交/刷新
我有以下设置:
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
<property name="persistenceUnitName" value="persistenceUnit"/>
<property name="dataSource" ref="local-dataSource"/>
<property name="packagesToScan" value="X"/>
<property name="persistenceXmlLocation" value="classpath:persistence.xml"/>
</bean>
首先,确保在这些多通注释上使用fitting CascadeType
其次,entityManager/session中的合并操作不会通过引用保持对象相等。这意味着,在执行合并的更新情况下,检查是否返回了不同的对象。您应该始终使用保存操作的返回值。使用JPA的实体对象主要有三种类型:
CascadeType.MERGE
,并让实体A引用分离的实体B,则执行MERGE()实体A上的
将首先到实体B上的合并(),使其处于管理状态。当实体A随后被存储时,它具有对托管B的引用,并且关系被持久化。(如果还希望持久化对数据库中不存在的对象的引用,请同时添加CascadeType.persist
。)根据您和其他评论,我在我的多通关系中添加了以下内容。optional=true,cascade={CascadeType.MERGE,CascadeType.PERSIST}我已将CascadeType.MERGE添加到所有子依赖项中。我可以看到使用session.contains(person)时,此实体不受会话管理。根据你的描述,我相信这会使我的物体分离。如何重新连接它们?合并->使用返回的对象->保存或更新?(正在尝试)当我在保存或更新中使用合并返回的person对象时,我得到:非法尝试将集合与两个打开的会话关联不确定这是否更好或更糟这是怎么标记的?这是一个非常笼统的答案,而不是针对手头的问题。@JamesB我不同意,这是对可能导致问题的原因的详细解释,以及3种可能的解决方案。@Puttzy从当时提供的内容来看,我认为Hibernate的
SAVE\u UPDATE
cascade应该可以做到这一点,无需更改Dao代码。但是删除Person
中getManagementCode
上的@LazyCollection
,该注释是针对集合(@*ToMany)的,而这不是。修订号是否在更新时增加?在您再次尝试保存这些Person对象之前,它们是否已被更改?如果您有任何主键冲突,这些可能会被宣布为一个错误。这也将有助于了解有关问题的更多代码。如何为Person定义主键?我的更新中没有出现冲突或异常。至于我在操作什么…现在我已经对它进行了简化,以更新first-name属性。当我输出之前和之后的人员obejct时,我可以看到差异伟大的建议bu
private int personid;
private String firstName;
private String lastName;
private Store store;
private ManagementCode managementCode;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "personid", unique = true, nullable = false)
public int getPersonid() {
return this.personid;
}
/*a bunch of getters and setters*/
@ManyToOne(fetch = FetchType.LAZY, optional = true, cascade = {CascadeType.MERGE, CascadeType.PERSIST})
@org.hibernate.annotations.Cascade( {org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.PERSIST})
@LazyCollection(LazyCollectionOption.EXTRA)
@JoinColumn(name = "managementlevel", nullable = true)
public ManagementCode getManagementCode() {
return this.managementCode;
}
@ManyToOne(fetch = FetchType.LAZY, optional = true, cascade = {CascadeType.MERGE, CascadeType.PERSIST})
// @org.hibernate.annotations.Cascade( {org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.PERSIST})
@JoinColumn(name = "storeid", nullable = false)
public Store getStore() {
return this.store;
}
/*fields + getters and setter */
@OneToMany(fetch = FetchType.LAZY, mappedBy = "store", cascade = {CascadeType.MERGE, CascadeType.PERSIST})
@LazyCollection(LazyCollectionOption.EXTRA)
@JsonIgnore
public Set<Person> getPersons() {
return this.persons;
}
/**
* (Optional) The operations that must be cascaded to
* the target of the association.
*
* <p> By default no operations are cascaded.
*/
CascadeType[] cascade() default {};
@ManyToOne(optional = true, cascade = {CascadeType.MERGE, CascadeType.PERSIST}, fetch = EAGER)
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
<property name="persistenceUnitName" value="persistenceUnit"/>
<property name="dataSource" ref="local-dataSource"/>
<property name="packagesToScan" value="X"/>
<property name="persistenceXmlLocation" value="classpath:persistence.xml"/>
</bean>
@Repository
public class EventRepository {
@PersistenceContext
EntityManager entityManager;
@Transactional
public void persist(Event event) {
entityManager.persist(event);
}
}