用spring-data懒惰地评估

时间:2019-05-28 16:16:26

标签: java jpa spring-data-jpa

我想让角色设置为延迟获取。 Hibernate fetchType.Lazy在这种情况下(使用spring数据)不起作用。我一直在尝试诸如Entitygraph之类的许多可能性,但是它们都无法解决这个问题,或者我在错误地使用它们。 我有下节课:

A类用户:

[1] <div><b>This is possibly an article heading</b><font style="FONT-SIZE: 10pt;"> This is the <i>body</i> of the article.</font><font style="FONT-SIZE: 10pt;"> It could have <i><b>interesting tags</b></i> embedded in the text</font></div>
[2] <p id="SomeId"><b>This is another article heading</b><font style="FONT-SIZE: 10pt;"> This is the <i>body</i> of the second article.</font><p><font style="FONT-SIZE: 10pt;"> It could have further <i><b><u>interesting tags</u></b></i> embedded in the text</font></p></p>  

A类角色:

@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;

}

服务:

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

       @Id
       private int roleId;

       private String roleName;

    }

存储库:

 @Service
    public class UserService implements IUserService{

        @Autowired
        UserRepository repository;

        public User findUserByLdapId(String loginName) {

            return repository.findUserByLdapId(loginName);
        }
    }

控制器:

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

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


}

所以json看起来像:

@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);

    };
}

谢谢!

2 个答案:

答案 0 :(得分:0)

您似乎在要求两个不同的内容:如何懒惰地获取@OneToMany关联(应该可以立即使用)以及如何使JSON像上面那样(与它无关) JPA实体提取的配置方式)。

如果您使用Jackson序列化实体,则默认情况下,所有字段都将被序列化,包括那些延迟获取的字段。如果开始序列化实体时持久性上下文仍处于打开状态,Jackson将通过访问该属性来触发延迟加载。结果,无论您使用FetchType.EAGER还是FetchType.LAZYroles 都将包含在结果中(我想是这样,因为您d如果上下文已关闭,则获取LazyInitializationException

简单地,解决方案是告诉杰克逊,如果您不希望在结果中使用该属性,则不要使用roles序列化@JsonIgnore

答案 1 :(得分:0)

首先,Hibernate和Spring Data是为不同目的而设计的完全不同的工具,它们可以很好地相互配合。您可以在此处详细了解两者之间的区别:What Is the Difference Between Hibernate and Spring Data JPA?

Spring Data与如何获取实体的相关集合无关,而Hibernate作为JPA的实现则如此。

我假设您确实懒惰地获取集合,并且这在实体序列化期间发生,因此该机制可以正常工作。

我建议您创建某种DTO对象,您可以从控制器返回它而不是返回实体。似乎您不想公开用户的角色,因此创建没有角色的DTO可能是个好主意。另一种解决方案是指示Jackson使用roles批注在序列化过程中忽略@JsonIgnore属性。