2011-09-28 2 views
0

저는 Spring, Struts, Hibernate 및 JPA를 사용하는 응용 프로그램을 보유하고 있습니다. 그래서 회사와 위치라는 두 개의 엔티티가 있습니다. 회사는 위치와 oneToMany 관계에 있고 회사에 ManyToOne에 위치합니다.데이터 원본에 트랜잭션이 serializable로 설정된 경우 oneToMany 양방향이 작동하지 않습니다.

위치 법인 :

@Entity<br> 
@Table(name = "locations")<br> 
@Access(AccessType.PROPERTY)<br> 
public class Location implements Serializable, Comparable<Location> { 

    private Company company; 

    @ManyToOne 
    @JoinColumn(name="company_id") 
    public Company getCompany(){ 
     return this.company; 
    } 

    public void setCompany(Company c){  
     this.company = c; 
    } 
} 


회사 법인 :

@Entity 
@Access(AccessType.PROPERTY) 
@Table(name = "company") 
public class Company implements Serializable { 

    private Integer id; 
    private String name; 

    private List<Location> locations; 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    @Column(name = "id") 
    public Integer getId() { 
     return id; 
    } 

    public void setId(Integer id) { 
     this.id = id; 
    } 

    @Column(name = "name") 
    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    @OneToMany(mappedBy="company") 
    public List<Location> getLocations(){ 
     return this.locations; 
    } 

    public void setLocations(List<Location> l){ 
     this.locations = l; 
    } 

    public void addLocation(Location l){ 

     if (locations == null) 
      locations = new ArrayList<Location>(); 

     if (!locations.contains(l)) 
       locations.add(l); 

     if (l.getCompany()!=this) 
      l.setCompany(this); 
    } 

    public void removeLocation(Location l){ 

     if (locations != null){    
      if (locations.contains(l)) 
       locations.remove(l); 
     } 
    } 
} 

다음 내가 locationService의 방법이 새 위치를 추가 할 때 :

,

GenericService :

public abstract class GenericService { 

protected Logger logger = Logger.getLogger(getClass()); 

@PersistenceContext(type = PersistenceContextType.EXTENDED,unitName = "MyPU") 
protected EntityManager em; 

public void setEntityManager(EntityManager em) { 
    this.em = em; 
} 

public EntityManager getEntityManager() { 
    return em; 
} 

}

위치 서비스 : 나는 conection에 풀로 내가 거래를 활성화 한 글래스 피쉬 JDBC 연결 풀을 사용하도록 지정해야

@Transactional 
public class LocationServiceImpl extends GenericService implements iLocationService { 
    @Override 
    public Boolean saveLocation(LocationForm lf) { 

      Location l = new Location(); 
      Company c = companyService.getCompany(lf.getCompanyForm().getId()); 
      // set all location properties here from LocationForm Obj   

      l.setCompany(c); 
      this.em.persist(l);   
       c.addLocation(l); 
      return true; 
    } 
} 

반복 읽기 수준. 이제 모든 것이 정상이지만, 반복 가능한 읽기에서 직렬화 가능 saveLocation 메소드로의 전환이 더 이상 작동하지 않으면.

INFO: DEBUG [http-thread-pool-8080(5)] (SQLStatementLogger.java:111) - 
insert 
into 
    locations 
    (company_id, emailTransfer, liveTransfer, name, outbound_prefix, queue_id, smsTransfer, welcomeMessage) 
values 
    (?, ?, ?, ?, ?, ?, ?, ?) 
INFO: DEBUG [http-thread-pool-8080(5)] (SQLStatementLogger.java:111) - 
select 
    locations0_.company_id as company9_153_1_, 
    locations0_.id as id1_, 
    locations0_.id as id146_0_, 
    locations0_.company_id as company9_146_0_, 
    locations0_.emailTransfer as emailTra2_146_0_, 
    locations0_.liveTransfer as liveTran3_146_0_, 
    locations0_.name as name146_0_, 
    locations0_.outbound_prefix as outbound5_146_0_, 
    locations0_.queue_id as queue6_146_0_, 
    locations0_.smsTransfer as smsTrans7_146_0_, 
    locations0_.welcomeMessage as welcomeM8_146_0_ 
from 
    locations locations0_ 
where 
    locations0_.company_id=? 


을 그럼 내가 얻을 : applicationContext.xml

에서

INFO: WARN [http-thread-pool-8080(5)] (JDBCExceptionReporter.java:233) - SQL Error: 1205, SQLState: 41000 

INFO: ERROR [http-thread-pool-8080(5)] (JDBCExceptionReporter.java:234) - Lock wait timeout exceeded; try restarting transaction 

일부

<bean id="txManagerVA" class="org.springframework.orm.jpa.JpaTransactionManager"> 
     <property name="entityManagerFactory" ref="emfVA" />   
</bean> 
    <bean id="emfVA" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="vsDS" /> 
    <property name="persistenceUnitName" value="MyPU"/> 
</bean> 

    <jee:jndi-lookup id="vsDS" jndi-name="jdbc/MyJndiDS"/> 

<tx:annotation-driven transaction-manager="txManagerVA" /> 

에게 그것을 내가 직렬화 트랜잭션 수준 saveLocation()을 실행할 때
이 디버그 로그입니다 그 삽입 후 테이블이 잠겨있어 다른 작업을 수행 할 수없는 것 같습니다. 전에 내가 말한대로 트랜잭션 격리를 반복 가능으로 변경하면 모든 것이 정상입니다.
누군가이 동작을 설명 할 수 있습니까?

+0

어떻게 코드를 표시 할 수 있습니까? – gkamal

+0

질문에 답변하기 위해 코드를 업데이트했습니다. –

+0

괜찮아 보입니다. 여러 em 또는 연결이 만들어지고 있는지 확인하기 위해 로그를보고 어쩌면 몇 가지 포인터를 제공 할 수 있습니다. 유일한 설명은 어떤 이유로 여러 개의 트랜잭션이 생성된다는 것입니다. 이 두 가지가 동일한 트랜잭션의 일부로 시작되면 격리 수준은 중요하지 않습니다. 어떤 데이터베이스를 사용하고 있습니까? 동일한 JDBC 코드를 시뮬레이트 할 수 있습니까? – gkamal

답변

0

그런 다음 기업 어디 이제까지 위치를 추가하고 locations.You 그렇지 않으면 교착 상태로 동작하고 회사를 저장 캐스케이드 수준

@OneToMany(mappedBy="company", cascade = CascadeType.ALL) 
    public List<Location> getLocations(){ 
     return this.locations; 
    } 

추가

감사합니다.

+0

좋아, 나는 그것을 이해하지만, 지금 나는 회사에 위치를 추가하려하고 다른 방법은 안된다. –

+0

예. 회사에 위치 정보를 추가하고 회사를 저장하거나 업데이트하면됩니다. 코드에서 데이터베이스에 위치를 저장하고 교착 상태의 원인이되는 회사를 업데이트합니다. 내 솔루션을 시도하면 내 뜻을 알 수 있습니다. – Shahzeb

관련 문제