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.