저는 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()
을 실행할 때
이 디버그 로그입니다 그 삽입 후 테이블이 잠겨있어 다른 작업을 수행 할 수없는 것 같습니다. 전에 내가 말한대로 트랜잭션 격리를 반복 가능으로 변경하면 모든 것이 정상입니다.
누군가이 동작을 설명 할 수 있습니까?
어떻게 코드를 표시 할 수 있습니까? – gkamal
질문에 답변하기 위해 코드를 업데이트했습니다. –
괜찮아 보입니다. 여러 em 또는 연결이 만들어지고 있는지 확인하기 위해 로그를보고 어쩌면 몇 가지 포인터를 제공 할 수 있습니다. 유일한 설명은 어떤 이유로 여러 개의 트랜잭션이 생성된다는 것입니다. 이 두 가지가 동일한 트랜잭션의 일부로 시작되면 격리 수준은 중요하지 않습니다. 어떤 데이터베이스를 사용하고 있습니까? 동일한 JDBC 코드를 시뮬레이트 할 수 있습니까? – gkamal