我是Spring Data JPA的新手,并且我正在使用ManyToOne关系处理两个实体(用户和角色)。定制JpaRepository可以在执行User查询时获取Role,但是,即使select语句包含联接select,也没有设置Role的任何字段,但Role的@Id除外。 我该怎么做才能确保测试用例可以通过?
问题:
java.lang.AssertionError: Expecting <com.lenovo.dcg.epic.server.user.Role@36511c97> to have a property or a field named <"displayName"> with value <"Administrator"> but value was: <null>
和日志:
2018-09-11 23:22:10.885 INFO 56280 --- [ Test worker] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory
Hibernate:
/* select
generatedAlias0
from
User as generatedAlias0
where
generatedAlias0.username=:param0 */ select
user0_.userID as userID1_2_0_,
role1_.roleTypeID as roleType1_1_1_,
user0_.createdBy as createdB2_2_0_,
user0_.createdDate as createdD3_2_0_,
user0_.email as email4_2_0_,
user0_.firstName as firstNam5_2_0_,
user0_.lastMaintainedBy as lastMain6_2_0_,
user0_.lastMaintainedDate as lastMain7_2_0_,
user0_.lastName as lastName8_2_0_,
user0_.RoleTypeID as RoleTyp11_2_0_,
user0_.title as title9_2_0_,
user0_.username as usernam10_2_0_,
role1_.createdBy as createdB2_1_1_,
role1_.createdDate as createdD3_1_1_,
role1_.displayName as displayN4_1_1_,
role1_.lastMaintainedBy as lastMain5_1_1_,
role1_.lastMaintainedDate as lastMain6_1_1_,
role1_.roleTypeDesc as roleType7_1_1_
from
users user0_
left outer join
role_types role1_
on user0_.RoleTypeID=role1_.roleTypeID
where
user0_.username=?
2018-09-11 23:22:11.054 TRACE 56280 --- [ Test worker] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [xxx]
这是我的用户实体。
@NamedEntityGraph(name = "User.detail", includeAllAttributes = true)
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Integer userID;
@Column(nullable = false, unique = true)
String username;
@Column(nullable = false)
String firstName;
@Column(nullable = false)
String lastName;
@Column(nullable = false)
String email;
@ManyToOne
@JoinColumn(name = "RoleTypeID", nullable = false)
@JsonProperty(value = "RoleTypeID")
@JsonDeserialize(using = UserRoleComponent.UserRoleDeserializer.class)
@JsonSerialize(using = UserRoleComponent.UserRoleSerializer.class)
Role role;
String title;
@JsonIgnore
@CreationTimestamp
Timestamp createdDate;
@Column(nullable = false)
String createdBy;
@Column(nullable = false)
String lastMaintainedBy;
@JsonIgnore
@UpdateTimestamp
Timestamp lastMaintainedDate;
}
这是我的角色实体。
@Entity
@Table(name = "role_types")
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Integer roleTypeID;
String roleTypeDesc;
String displayName;
@CreationTimestamp
Timestamp createdDate;
String createdBy;
@UpdateTimestamp
Timestamp lastMaintainedDate;
String lastMaintainedBy;
}
我的存储库:
public interface UserRepository extends JpaRepository<User, Integer> {
@EntityGraph(value = "User.detail", type = EntityGraphType.LOAD)
Optional<User> findByUsername(String username);
}
和我的测试用例:
@RunWith(SpringRunner.class)
@DataJpaTest(properties = {"spring.jpa.properties.hibernate.format_sql=true",
"spring.jpa.properties.hibernate.use_sql_comments=true",
"logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE"})
public class UserRepositoryTest {
@Autowired
private TestEntityManager entityManager;
@Autowired
private UserRepository repository;
private User user;
private void initRoleType() throws ParseException {
Role admin = new Role();
admin.setRoleTypeDesc("Administrator");
admin.setDisplayName("Administrator");
admin.setCreatedBy("xxx");
admin.setLastMaintainedBy("xxx");
admin = entityManager.persist(admin);
Role manager = new Role();
manager.setRoleTypeDesc("Manager");
manager.setDisplayName("Manager");
manager.setCreatedBy("xxx");
manager.setLastMaintainedBy("xxx");
manager = entityManager.persist(manager);
Role user = new Role();
user.setRoleTypeDesc("User");
user.setDisplayName("User");
user.setCreatedBy("xxx");
user.setLastMaintainedBy("xxx");
user = entityManager.persist(user);
entityManager.flush();
}
@Before
public void setUp() throws Exception {
resetIdentity();
initRoleType();
user = new User();
user.setUsername("xxx");
user.setFirstName("xxx");
user.setLastName("xxx");
user.setEmail("xxx@xxx.com");
Role admin = new Role();
admin.setRoleTypeID(1);
user.setRole(admin);
user.setTitle("Developer");
user.setCreatedBy("admin");
user.setLastMaintainedBy("admin");
}
private void resetIdentity() {
EntityManager em = entityManager.getEntityManager();
Query query = null;
query = em
.createNativeQuery("ALTER TABLE role_types ALTER COLUMN roleTypeID RESTART WITH 1");
query.executeUpdate();
}
@Test
public void testFindUserByName() {
repository.save(user);
entityManager.flush();
Optional<User> user = repository.findByUsername("xxx");
assertThat(user).isNotEmpty();
assertThat(user).hasValueSatisfying(u -> {
assertThat(u).hasFieldOrPropertyWithValue("userID", 1);
assertThat(u.getRole()).isNotNull();
assertThat(u.getRole()).hasFieldOrPropertyWithValue("roleTypeID", 1);
assertThat(u.getRole()).hasFieldOrPropertyWithValue("displayName", "Administrator");
assertThat(u.getDisplayName()).isEqualTo("Administrator");
});
}
}