Akhil
Akhil

Reputation: 1254

Spring Data JPA findOne returns null

I'm using Spring Data JPA and I'm facing a very weird issue with findOne method which is returning null even though the row is present in DB.

I have a consumer thread which takes an id from a queue and tries to fetch the entity from DB which always returns null, however if I pause thread (by putting a breakpoint before method call) then it fetches the entity from DB but returns null in normal execution of program, I know it sounds weird with breakpoint stuff but it is what it is, may be I'm missing something. My code looks like below:-

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

I'm not using any transaction in "employeeService" as it is not required as it is a read operation.

My service looks like

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

And my model looks like:-

   @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

}

Can somebody point me where I'm mistaking.

Upvotes: 1

Views: 7572

Answers (1)

Naros
Naros

Reputation: 21103

The Spring 4.2 way to do this would be to introduce a @TransactionEventListener annotated method on a spring component to handle the callback. You then simply need to publish an event and let the event framework do its thing:

// 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
  }
}

Upvotes: 2

Related Questions