2017-02-14 1 views
0

스프링 데이터 JPA를 사용하고 있으며 행이 DB에 있어도 null을 반환하는 findOne 메서드에 매우 이상한 문제가 있습니다.스프링 데이터 JPA findOne이 null을 반환합니다.

나는 대기열에서 ID를 가져 와서 항상 null을 반환하는 DB에서 엔티티를 가져 오려고하는 소비자 스레드가 있지만, 스레드를 일시 중단하면 (메서드 호출 전에 중단 점을 넣어서) DB에서 엔티티를 가져옵니다. 하지만 프로그램의 정상적인 실행에 null을 반환, 나는 그것이 중단 점 물건과 이상한 소리 알아하지만 그것은 무엇인지, 내가 뭔가를 놓치고 수 있습니다. 내 코드는 다음과 같다 : - 그것은 읽기 작업이기 때문에 필요하지 않은 것처럼

 if (id > 0) { 
     employee = employeeService.get(id); 
     if (employee == null) { 
      logger.error(String.format("No employee found for id : %d", 
         id)); 
      return; 
    } 

내가 "employeeService"에서 트랜잭션을 사용하지 않는. 내가 착각하고있어 어디

@Entity 
    @Table(name = "employee") 
    @JsonInclude(JsonInclude.Include.NON_NULL) 
    public class Employee implements Serializable { 

    private static final long serialVersionUID = 1681182382236322985L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private long id; 

    @Column(name = "name") 
    private String name; 

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
    @JoinColumn(name = "emplopyee_id") 
    @Fetch(FetchMode.SELECT) 
    private List<Address> addresses; 

    // getter/setter and few fields have been omitted 

}

누군가가 날 포인트 -이 :

public Employee get(long id) { 
    return employeeDao.findOne(id); 
} 

그리고 내 모델의 모습처럼

내 서비스가 보인다.

+1

읽기 작업을위한 트랜잭션이 필요 없다는 것은 신화입니다. Hibernate에 접근 할 때마다 트랜잭션을 가져야한다. 격리 (ACID의 I)도 중요하며 트랜잭션이 필요합니다. –

+0

나는 트랜잭션을 사용해 보았고 readOnly로 표시했지만 여전히 null 값을 얻고있다. – Apollo

+1

'employeeService.get'에 관련된 코드를 보여줄 수 있습니까? – Naros

답변

2

이렇게하려면 Spring 구성 요소에 @TransactionEventListener 주석 메소드를 도입하여 콜백을 처리해야합니다. 그런 다음 이벤트를 게시하고 이벤트 프레임 워크가 수행하도록하면됩니다.

// Spring component that handles repository interactions 
@Component 
public class ProducerService implements ApplicationContextAware { 
    private ApplicationContext applicationContext; 

    @Transactional 
    public void doSomeThingAwesome(String data) { 
    MyAwesome awesome = new MyAwesome(data); 
    myAwesomeRepository.save(awesome); 
    applicationContext.publishEvent(new MyAwesomeSaved(awesome.getId())); 
    } 
} 

// Spring component that handles the AFTER_COMMIT transaction callback 
// This component only fires when a MyAwesomeSaved event is published and 
// the associated transaction it is published in commits successfully. 
@Component 
public class QueueIdentifierHandler { 
    @TransactionalEventListener 
    public void onMyAwesomeSaved(MyAwesomeSaved event) { 
    Long entityId = event.getId(); 
    // post the entityId to your queue now 
    } 
} 
+0

와우, 멋진 솔루션입니다. – Apollo

관련 문제