2013-12-10 5 views
0

내 응용 프로그램 j2ee + spring mvc + jpa (eclipselink, database oracle)는 다른 항목을 제거한 후에도 항목을 유지할 때 문제가 있습니다. 항목 또는 다른 항목을 제거하면 다음 지속 기능은 이전에 삭제 한 항목을 db에 삽입합니다. 서비스에서jpa em.persist 이전에 삭제 된 항목 삽입

@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입니다 (이름 = "PORTFOLIO_ITEMS")

: 모델에서 나는이 클래스 프로파일에 대한 매핑이 나는이 단계를 수행하면 나는이 방법 createPortfolioItem 전자의 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();  
    } 

있습니다

,
  1. 가 A 및 B는
  2. 만 B가 DB에 deletePortfolioItem와
  3. 삭제 소자 A
  4. 가 DB에 createPortfolioItem과 C 원소를 만들있다있는 DB에 createPortfolioItem와 요소 A와 B를 만드는 , B 및 C

제발, 도와주세요!

는 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; 
    } 
} 

이기 난이 방법이 난 컨트롤러 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> 

이 스프링과 같은 형태의 데이터를 받아 PortfolioItem의 객체를 생성 :

@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

이 3 단계의 코드와 PortofolioItem의 코드를 보여주세요. 또한 질문 : 왜 캐시에서 모든 것을 제거합니까? 네가 그걸 필요로하는지 의심 스럽네. –

+0

em.getEntityManagerFactory()를 추가했습니다.getCache(). evictAll(); 왜냐하면 나는 그것이 캐시 문제라고 생각했기 때문에 작동하지 않았기 때문이다. – user3083618

답변

0

나는이 코드에 오류가 있다고 생각하지 않지만 어쩌면 다시 0123을 사용하고 있습니다./PortfolioItem, 어쩌면 일부는 @SessionScoped/@ViewScoped 콩 또는 이와 동등한 것으로 저장됩니다.

다른 2 가지 :

1) getPortfolio() 때문에 당신이 간단하게 할 수있는, cascade=PERSIST 표시됩니다 :

@Transactional 
@Override 
public void create(PortfolioItem portfolioItem,Profile profile) throws BusinessException 
{ 
    profile.getPortfolio().add(portfolioItem); 
    em.merge(profile); 
} 

2) 당신이 EJB의 트랜잭션 내에서로드 엔터티를 다시 병합 할 필요가 없습니다 방법 :

@Transactional 
@Override 
public void deletePortfolioItem(int portfolioItemID) throws BusinessException 
{ 
    PortfolioItem p = em.find(PortfolioItem.class, portfolioItemID); 
    em.remove(p); 
    em.getEntityManagerFactory().getCache().evictAll();  
} 
+0

컨트롤러에서 나는 스프링 폼으로부터 객체를 가져 와서 persist를위한 서비스를 호출한다. em.getEntityManagerFactory()를 추가했습니다. getCache(). evictAll(); 캐시 문제이지만 작동하지 않는다고 생각했기 때문입니다. – user3083618

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); 

을 대신 당신이 em.flush()를 호출 할 수있는 cache.evictAll()와 함께 연주의.

관련 문제