简体   繁体   中英

Evaluate lazily with spring-data

I would like to have the roles set fetch lazily. Hibernate fetchType.Lazy doesn't work for this cases, where spring data is used. I 've been trying lots of possibilities like Entitygraph but none of them works on this, or I'm using them wrong. I have the next classes:

A class User:

@Entity
@JsonRootName(value = "user")
@Table(name = "web_users", schema = "t_dw_comercial")
public class User {

   @Id
   private int userId;

   private String fullName;

    @OneToMany(fetch=FetchType.LAZY)
    @JoinTable(name="web_users_roles",
    joinColumns = {@JoinColumn(name="user_id")},
    inverseJoinColumns = {@JoinColumn(name="role_id")}
    )
    private List<Role> roles;

}

A class Role:

    @Entity
    @JsonRootName(value = "roles")
    @Table(name = "web_roles", schema = "t_dw_comercial")
    public class Role {

       @Id
       private int roleId;

       private String roleName;

    }

Service:

 @Service
    public class UserService implements IUserService{

        @Autowired
        UserRepository repository;

        public User findUserByLdapId(String loginName) {

            return repository.findUserByLdapId(loginName);
        }
    }

Repository:

@Repository
public interface UserRepository extends CrudRepository<User, Long>{

    @Query("SELECT u FROM User u where u.ldapId= ?1")
public User findUserByLdapId(String loginName);


}

Controller:

@Controller
@RestController
public class UserController {

    @Autowired
    private IUserService userService;

    @CrossOrigin
    @RequestMapping(value = "/dashboard", params = {"user"}, method = RequestMethod.GET,  produces = "application/json")
    public ResponseEntity<User>  getUser(@RequestParam(value = "user") String ldapId) {

        User user =  userService.findUserByLdapId(ldapId);

        if(user == null)
            return new ResponseEntity<>(HttpStatus.NO_CONTENT);

        return new ResponseEntity<>(user, HttpStatus.OK);

    };
}

So a json would looks like:

{
    "user": {
        "userId": 1,
        "fullName": "Carolina Ponce",
        "roles":[]
    }
}

Thanks in advance!

It seems you're asking for two different things: how to fetch @OneToMany association lazily (which should work out of the box) and how to make your JSON look like the above (which has nothing to do with how your JPA entity fetching is configured).

If you serialize your entity using Jackson, by default all the fields will get serialized, including those that are fetched lazily. If the persistence context is still open when you begin to serialize the entities, Jackson will simply trigger lazy loading by accessing the property. As a result, regardless of whether you use FetchType.EAGER or FetchType.LAZY , roles will be included in the result (I assume it is the case, since you'd be getting a LazyInitializationException if the context was closed).

The solution is, simply, to tell Jackson to refrain from serializing roles using @JsonIgnore if you don't want the property in the result.

First of all Hibernate and Spring Data are totally different tools designed for different purposes and they work with each other just fine. You can read more about the differences between both here: What Is the Difference Between Hibernate and Spring Data JPA?

Spring Data has nothing to do with how you fetch entity's related collections, Hibernate, as an implementation of JPA, does.

I assume you indeed fetch your collection lazily and that happens during serialization of your entity so the mechanism works as it should.

I suggest you to create some sort of DTO object that you could return from your controller rather than returning an entity. It seems like you don't want to expose user's roles so creating a DTO without roles may be a good idea. Other solution is to instruct Jackson to ommit roles property during serialization using @JsonIgnore annotation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM