0

I am using Spring boot from a couple of years now but recently I encountered an unusual error. While calling the spring boot app's GET API from my angular app, it is returning less number of rows than the actual number present on DB.

The above mentioned issue is resolved the moment spring boot app is redeployed. Suspecting it to be some sort of caching issue I have kept this title.

Note: I have not enabled caching on the app.

Another suspect is EntityManager not getting refreshed. I'm using Spring repository to fetch the data, entity manager is not handled by my custom code. So, I'm not sure how that can happen.

I am using AWS RDS postgresql instance as my db.

After two days of unsuccessful pursuit, I put it here for expert's opinions

@Data
@EntityListeners(AuditingEntityListener.class)
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "uid_gen_seq")
    @SequenceGenerator(name = "uid_gen_seq", allocationSize = 1)
    @Column(name = "user_id", updatable = false, nullable = false)
    private long userId;
    private String name;
    private String address;
    @Column(name = "ph_no")
    private String phNo;
    @Column(name = "rent_pass")
    private int rentPass;
    @CreatedBy
    private String createdBy;
    @LastModifiedBy
    private String modifiedBy;
}

Controller method:

@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<UserVO>> getAllUsers()
        throws Exception, NoContentException {
    return ResponseEntity.ok(userService.getAllUsers());
}

Service method:

@Override
public List<UserVO> getAllUsers() throws NoContentException {
    logger.info("Get all users");
    List<User> users = userRepository.findAll();
    List<UserVO> userVOs = converter.convertToVO(users);
    return userVOs;
}

Update:

I think I have narrowed down the possible cases to 1. That's session not getting refreshed. As per my understanding, calling a repository method implicitly creates a session and closes it. Unless the service or controller method has been annotated with @Transactional.

The service methods in my case were not annotated with @Transactional, still the session was not getting refresh.

As a workaround I have annotated the methods with @Transactional(TxType.REQUIRED_NEW) to avoid any old session getting used. This is working as of now but I'm still not convinced with the behavior of the application without this workaround.

saurabh kedia
  • 181
  • 1
  • 9

1 Answers1

0

How are you inserting the data? if you are not inserting through your app, then the caches are not reloaded. See this answer - Are entities cached in jpa by default?

Yuvaraj G
  • 949
  • 5
  • 13
  • the data is being inserted in the same app, using a scheduled job and I'm not using caching. – saurabh kedia Apr 06 '20 at 11:13
  • The first level cache is enabled by default in hibernate, it is session scoped and you cannot disable it, probably you have to find a mechanism to refresh all session caches. To make sure this is the problem, try doing `session.refresh()` or `session.flush()` before you fetch the data. – Yuvaraj G Apr 06 '20 at 11:48
  • As per my understanding, that's L1(Persistence Context) caching which is valid only for a single Hibernate Session. Spring Repository uses Transaction management which closes the session internally, unless you use @Transaction (but that's another discussion). Moreover, the insert and fetch calls are two different calls with a large time-gap. I suspected this as I mentioned in the question but after analysing, i doubt if this could be the case – saurabh kedia Apr 06 '20 at 12:02