我已经在SO和许多其他网站上阅读并重读了所有内容,但似乎无法弄清楚为什么我更新的对象没有更新。
我正在做的基本概述:
服务层要求DAO提供一些人
从DB(DAO / @Repository)返回 People 的ArrayList
服务层操纵对象并将其添加到新的arraylist
服务层将新列表传递回DAO以进行更新
没有更新
如果我在我的对象中抛出一条日志消息有新的值,那么这些孩子就会正确补充水分。我在代码中没有错误,只是没有提交我的更改。
以下是一些代码:
PersonDAO 注释为@Repository
public void updatePeople(List<Person> people) {
log.info("Updating " + people.size() + " people");
try {
Transaction tx = getCurrentSession().beginTransaction();
for (Person person : people){
getCurrentSession().saveOrUpdate(person);
}
getCurrentSession().flush();
tx.commit();
getCurrentSession().close();
} catch (Exception e){
log.error("Exception Updating all people " + e.toString());
e.printStackTrace();
}
}
public List<Person> getAssociatesByStoreId(String storeId) {
try {
List<Person> usersInStore = (List<Person>) getCurrentSession()
.createCriteria(Person.class).createCriteria("store")
.add(Restrictions.eq("storeId", storeId)).list();
return usersInStore;
} catch (Exception e) {
log.error("exception in getAssociatesByStoreId ", e);
}
return null;
}
PersonService 注释为@Service - 相关方法
/* I put the people into a map to do some other logic on them */
for (Person person : personDAO.getAllPeople()){
personMap.put(person.getEmployeeId() + "-" + person.getStore().getStoreId(), person);
}
/*
I iterate a list creating new Person objects (based on some random stuff),
including saving any children entities (managementcodes and stores) that need to be created
After I have created a new Person I attempt to find it in the map from above.
If I find it pull it out of the map and put it into an array list
that is eventually passed back into the DAO
*/
人 注明为@Entity
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;
}
编辑我在上面添加了两组Cascade类型的注释但仍然没有运气
编辑2 更新了以显示主键定义 在我踢小狗之前,请有人帮助我。 感谢
答案 0 :(得分:1)
可能是您需要在ManyToOne注释上使用“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 {};
例如
@ManyToOne(optional = true, cascade = {CascadeType.MERGE, CascadeType.PERSIST}, fetch = EAGER)
更新: 如果您使用的是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>
DAO课程:
@Repository
public class EventRepository {
@PersistenceContext
EntityManager entityManager;
@Transactional
public void persist(Event event) {
entityManager.persist(event);
}
}
答案 1 :(得分:1)
JPA有三种主要类型的实体对象:
为了保持实体与另一个实体之间的关系,引用的实体必须进行管理。有多种方法可以实现这一目标。
CascadeType.MERGE
,让实体A引用一个分离的实体B,然后在实体A上执行merge()
将首先到实体B上的merge()
,使其得到管理。然后,当存储实体A时,它具有对托管B的引用,并且该关系是持久的。 (如果您还想继续引用尚未包含在数据库中的对象,请同时添加CascadeType.PERSIST
。)答案 2 :(得分:0)
首先,确保在那些ManyToOne注释上使用拟合CascadeType。
其次,entityManager / session中的合并操作不会通过引用保持对象相等。这意味着,在执行合并的更新情况下,检查是否返回了不同的对象。您应该始终使用保存操作的返回值。