简体   繁体   中英

Why LoadGraphs does not work?

I have a repository for users and roles. Both entities have different tables in DB. I try to get load Role like Hibernate.initialize(User.getRole()) or same idea from User u join fetch u.role where u.username := username and u.password := password but use Spring data CrudRepository with LoadGraphs. But when I call findDistinctFirstByUsernameAndPassword then I get Exception. Please help me fix this issue. Thank You.

Repository:

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

Exception:

WARN: HHH000104: firstResult/maxResults specified with collection fetch; applying in memory! Hibernate: select distinct user0_.id as id1_1_0_, role1_.user_role_id as user_rol1_0_1_, user0_.enabled as enabled2_1_0_, user0_.password as password3_1_0_, user0_.username as username4_1_0_, role1_.role as role2_0_1_, role1_.username as username3_0_1_, role1_.username as username3_0_0__, role1_.user_role_id as user_rol1_0_0__ from users user0_ left outer join user_roles role1_ on user0_.id=role1_.username where user0_.username=? and user0_.password=? авг 16, 2017 10:21:41 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions WARN: SQL Error: 0, SQLState: 42883 авг 16, 2017 10:21:41 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions ERROR: ERROR: operator does not exist: integer = character varying No operator matches the given name and argument type(s). You might need to add explicit type casts. Position: 383

org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet

This is Entities :

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

}

Database schema:

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

Run approach:

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

I believe that your entity definition is incorrect, as can be seen in the executed SQL:

... on user0_.id=role1_.username

Have a look at the JPA example from Wikibooks . In your case it should be

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

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

(the column username should be removed from Role )

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