为什么LoadGraphs不起作用?

时间:2017-08-16 19:22:43

标签: java spring spring-data spring-data-jpa

我有一个用户和角色的存储库。两个实体在DB中都有不同的表。我尝试像Role或同样的想法Hibernate.initialize(User.getRole())一样加载from User u join fetch u.role where u.username := username and u.password := password,但在LoadGraphs中使用Spring数据CrudRepository。但是当我打电话给findDistinctFirstByUsernameAndPassword时,我得到了例外。请帮我解决这个问题。谢谢。

存储库:

public interface UserRepository extends CrudRepository<User, Integer> {
    @EntityGraph(value = "User.detail", type = EntityGraphType.LOAD)
    User findDistinctFirstByUsernameAndPassword(String username, String password);
}

例外:

  

警告:HHH000104:使用集合指定的firstResult / maxResults   取;在记忆中应用! Hibernate:选择不同的user0_.id为   id1_1_0_,role1_.user_role_id as user_rol1_0_1_,user0_.enabled as   enabled2_1_0_,user0_.password为password3_1_0_,user0_.username为   username4_1_0_,role1_.role as role2_0_1_,role1_.username as   username3_0_1_,role1_.username as username3_0_0__,   来自用户user0_ left outer的role1_.user_role_id as user_rol1_0_0__   在user0_.id = role1_.username where中加入user_roles role1_   user0_.username =?和user0_.password =? 2017年6月16日10:21:41 PM   org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions WARN:   SQL错误:0,SQLState:42883 2017年6月16日下午10:21:41   org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions错误:   错误:运算符不存在:整数=字符变化编号   运算符匹配给定的名称和参数类型。你可能需要   添加显式类型转换。职位:383

     

org.springframework.dao.InvalidDataAccessResourceUsageException:可以   不提取ResultSet; SQL [不适用];嵌套异常是   org.hibernate.exception.SQLGrammarException:无法解压缩   结果集

这是实体:

@Entity(name = "users")
@NamedEntityGraph(name = "User.detail", attributeNodes = @NamedAttributeNode("role"))
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(name = "username")
    private String username;

    @Column(name = "password")
    private String password;

    @Column(name = "enabled")
    private boolean enabled;

    @OneToMany()
    @JoinColumn(name = "username")
    private List<Role> role;
    ...set, get, empty constructor...
}

@Entity(name = "user_roles")
public class Role {
    @Id
    @Column(name = "user_role_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(name = "username")
    private String username;

    @Column(name = "role")
    private String role;
    ...set, get, empty constructor...

}

数据库架构:

CREATE TABLE users (
  id       SERIAL      NOT NULL,
  username VARCHAR(20) NOT NULL,
  password VARCHAR(20) NOT NULL,
  enabled  BOOLEAN     NOT NULL DEFAULT FALSE,
  PRIMARY KEY (username)
);

CREATE TABLE user_roles (
  user_role_id SERIAL PRIMARY KEY,
  username     VARCHAR(20) NOT NULL,
  role         VARCHAR(20) NOT NULL,
  UNIQUE (username, role),
  FOREIGN KEY (username) REFERENCES users (username)
);

运行方法:

private final ClassPathXmlApplicationContext context =
        new ClassPathXmlApplicationContext("spring-data-context.xml");

private UserRepository repository = context.getBean(UserRepository.class);

@Test
public void whenUserExistInDBThenGetUserWithLoadedRoles() {

    final User result = repository
            .findDistinctFirstByUsernameAndPassword("peter", "peter");

    assertNotNull(result);

    result.getRole().forEach(System.out::println);
}

1 个答案:

答案 0 :(得分:0)

我认为您的实体定义不正确,如执行的SQL中所示:

... on user0_.id=role1_.username

查看JPA example from Wikibooks。在你的情况下它应该是

public class User {
    ...
    @OneToMany
    private List<Role> role;
    ...
}

public class Role {
    ...
    @ManyToOne
    @JoinColumn(name = "username", referencedColumnName = "username")
    private User user;
    ...
}

(应从username

中移除Role