2017-02-14 233 views
0

我正在使用Spring Data JPA,並且即使行存在於數據庫中,findOne方法仍然返回null,所以我正面臨一個非常奇怪的問題。Spring Data JPA findOne返回null

我有一個消費者線程,它從隊列中獲取一個id並嘗試從DB中獲取總是返回null的實體,但是如果我暫停線程(通過在方法調用之前放置一個斷點),然後它從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」使用任何交易的,因爲它是一個讀操作它不是必需的。

我的服務看起來像

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

而且我的模型看起來像: -

@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 

}

有人能指出我在哪裏,我誤。

+1

不需要讀取操作的事務是一個神話。每次訪問Hibernate都應該有一個事務。隔離(ACID中的I)也很重要,並且需要交易。 –

+0

我嘗試使用事務並將其標記爲只讀但仍然收到空值。 – Apollo

+1

您能否在'employeeService.get'和實體映射中顯示相關代碼? – Naros

回答

2

Spring 4.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