我的应用程序j2ee + spring mvc + jpa(eclipselink,database oracle)在删除另一个项目后保留项目时出现问题。如果我删除一个或多个项目,则下一个持久性数据库会在数据库中插入先前删除的项目。在模型中,我有类Profile的映射:
@Entity
@Table(name = "PROFILES")
Class Profile {
private Collection<PortfolioItem> portfolio;
...
@OneToMany(orphanRemoval = true,cascade={PERSIST,MERGE,REFRESH,REMOVE})
@JoinColumn(name = "PROFILE_FK", referencedColumnName = "PROFILE_ID")
public Collection<PortfolioItem> getPortfolio() {
return portfolio;
}
}
类PortfolioItem是一个简单的POJO映射白色
@Entity @Table(name =“PORTFOLIO_ITEMS”)
在服务中我有两个方法createPortfolioItem e deletePortfolioItem
@Transactional
@Override
public void create(PortfolioItem portfolioItem,Profile profile)
throws BusinessException{
em.persist(portfolioItem);
profile.portfolio.add(portfolioItem);
em.merge(profile);
}
@Transactional
@Override
public void deletePortfolioItem(int portfolioItemID) throws BusinessException {
PortfolioItem p = em.find(PortfolioItem.class, portfolioItemID);
em.remove(em.merge(p));
em.getEntityManagerFactory().getCache().evictAll();
}
如果我按照以下步骤操作:
请帮帮我!
这是PortfolioItem类
@Entity
@Table(name = "PORTFOLIO_ITEMS")
public class PortfolioItem implements Serializable {
private int portfolioItemID;
private String title;
private String description;
private UploadedFile portfolioFile;
private static final long serialVersionUID = 1L;
public PortfolioItem() {
super();
}
@Id
@Column(name = "PORTFOLIOITEM_ID")
@GeneratedValue(generator = "PortfolioItem_Gen")
@SequenceGenerator(name = "PortfolioItem_Gen", sequenceName = "PortfolioItem_Seq", initialValue=1, allocationSize=1)
public int getPortfolioItemID() {
return this.portfolioItemID;
}
public void setPortfolioItemID(int portfolioItemID) {
this.portfolioItemID = portfolioItemID;
}
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
}
为了创建PortfolioItem的对象,我从jsp页面中的弹簧形式中获取数据
<form:form modelAttribute="portfolioItem" action="${pageContext.request.contextPath}/create" method="POST">
<form:errors path="title"/>
<form:input path="title" id="title" placeholder="Title"/>
<form:errors path="description"/>
<form:input path="description" id="description" placeholder="Description"/>
<button type="submit" class="standard_button medium">Sumbit</button>
</form:form>
在控制器中我有这样的方法:
@RequestMapping("/delete")
public String deletePortfolioItem(@RequestParam("portfolioItemID") int portfolioItemID) throws BusinessException{
service.deletePortfolioItem(portfolioItemID);
return "redirect:/profiles/views?profileID="+profile.getID();
}
@RequestMapping(value="/create",method=RequestMethod.GET)
public String createPortfolioStart(Model model){
model.addAttribute("portfolioItem", new PortfolioItem());
return "portfolio.createform";
}
@RequestMapping(value="/create",method=RequestMethod.POST)
public String createPortfolio(@ModelAttribute PortfolioItem portfolioItem,
@RequestParam("profileID") int profileID,
BindingResult bindingResult) throws BusinessException{
portfolioValidator.validate(portfolioItem, bindingResult);
Profile profile = service.findProfileByID(profileID);
service.create(portfolioItem,profile);
return "redirect:/profiles/views?profileID="+profile.getID();
}
答案 0 :(得分:0)
我不认为错误在于此代码,但您可能正在重新使用旧的Profile
/ PortfolioItem
存储,可能在某些@SessionScoped
/ {{1 bean或同等的。
另外两件事:
1)由于@ViewScoped
被标记为getPortfolio()
,您只需执行以下操作:
cascade=PERSIST
2)您不需要重新合并EJB事务方法中加载的实体:
@Transactional
@Override
public void create(PortfolioItem portfolioItem,Profile profile) throws BusinessException
{
profile.getPortfolio().add(portfolioItem);
em.merge(profile);
}
答案 1 :(得分:0)
我认为问题在于删除PortofolioItem
时的代码。在使用em.remove(portofolioItem)
删除它之前,您应该从配置文件集合的列表中删除它:
TypedQuery<Profile> query = em.createQuery("SELECT profile FROM Profile profile JOIN profile.portfolio portofolio where portofolio.id = :portofolioId", Profile.class);
query.setParameter("portofolioId", portofolioId);
Profile profile = query.getSingleResult();
profile.getprotofolio().remove(portofolio);
此外,您可以尝试拨打cache.evictAll()
,而不是使用em.flush()
。