2017-02-14 4 views
0

Я использую Spring Data JPA, и я сталкиваюсь с очень странной проблемой с методом findOne, который возвращает null, даже если строка присутствует в БД.Spring Data JPA findOne возвращает null

У меня есть потребительский поток, который принимает идентификатор из очереди и пытается извлечь объект из базы данных, который всегда возвращает 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. Изоляция (I в ACID) также важна и требует транзакций. –

+0

Я попытался использовать транзакцию и пометил ее как readOnly, но все равно получаю нулевое значение. – Apollo

+1

Можете ли вы показать соответствующий код в 'employeeService.get' и сопоставление сущности? – Naros

ответ

2

Весной 4.2 способ сделать это будет ввести аннотированный метод @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

Смежные вопросы