이 시나리오를 캡처 할 핵심 단어가 없기 때문에 설명해 보겠습니다. 수업은 단순화되었습니다.POJO DTO의 JPA 동기화/커밋 오류 (저장하지 않으려는 경우)
이 감안할 : 예외가 discountService.hasDiscount 던져
public ItemController {
@Autowired
ItemDtoService ItemDtoService;
@Autowired
DiscountService discountService;
@RequestMapping(value = "/viewItems", method = RequestMethod.POST)
public void process() {
List<ItemDto> ItemDtos = ItemDtoService.getItemDtos();
for(ItemDto i: ItemDtos) {
boolean isDiscounted = discountService.hasDiscount(i); //throws exception here on iteration 2 and the last iteration, ItemDto was discounted
if (isDiscounted) {
i.setPrice(discountService.getDiscountedPrice(i));
//do some other i.setter, basically modify the pojo
}
}
}
}
: 이후 반복
- 는 ItemDto이 할인되었습니다.
예외는 다음과 같습니다
Caused by: org.hibernate.exception.SQLGrammarException: could not update: [somepackage.ItemDto#364]
그리고 어딘가에 스택 트레이스에이 표시됩니다
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:456)"
문제는 그 메소드 호출입니다 즉 @Transactional입니다 밑에 DAO 방식을 사용 (그리고 아마도 그것은 단지 쿼리, 복잡한 쿼리 임에도 불구하고 좋은 이유로). JPA Tx 관리자가 메소드 호출 종료시 작업을 수행하면 pojo가 수정 된 것으로보고 동기화하려고 시도합니다. ItemDtoService.getItemDtos 안에는 getEntityManager(). createNativeQuery (nativeSql, ItemDto.class)가 사용되므로 ItemDto pojo에는 @Entity가 있습니다. 기타 5 가지 세부 정보는 다음과 같습니다.
@Entity
public class ItemDto{
//body
}
@Service
public class ItemService {
@Autowired
ItemDao itemDao;
public List<ItemDto> getItems() {
return itemDao.getItems(); //for sake of simplicity
}
}
@Repository
@Transactional
public class ItemDaoImpl {
public List<ItemDto> getItems() {
String nativeSql = "select...."
return getEntityManager().createNativeQuery(nativeSql, ItemDto.class);
}
}
@Service
public class DiscountService {
@Autowired
DiscountDao discountDao;
public boolean hasDiscount(ItemDto i) {
boolean hasDiscount = discountDao.hasDiscount(i);
//do other service stuff that might influence the hasDiscount flag
return hasDiscount;
}
}
@Repository
@Transactional
public class DiscountDaoImpl {
public boolean hasDiscount(ItemDto i) {
String nativeSql = "select...."
boolean hasDiscount;
//in reality the query is a complicated joins, executes and returns if has discount or not
return hasDiscount;
}
}
내가 뭘 잘못하고 있니?
내가 노력하고 일한 옵션 중 일부
은 다음과 같습니다 : 그들은 단지 쿼리 (사람들은 수 있습니다 부정적인 영향이 생각입니다 때문에- 가 다오 방법 에 @Transactional 제 (읽기 전용 = True)로 추가 의도적 복잡한 쿼리 때문에에는 트랜잭션 및 그것이 다음 할인되는 아이템 보는 통해 반복 2 개 루프 1이 상기 제어부에서
- ) 더티 판독 방지 변경을위한 별도의 루프를 생성하는 록킹을해야 할 수도 그 정보를 어딘가에 저장하십시오. 않는, 2 루프 나중에 참조 할 수의 변경은 POJO를
내가 다른 옵션을보고, 당신이 그것을 코딩 된 방법에 문제가 표시되는 경우 의견을주십시오하고있다. 목록 어쨌든 DTO 때문에
getEntityManager().clear();
그것은 잘 작동 하나는 기대 :