java - 实体的 Set contains 方法不起作用
问题描述
我正在尝试将实体与相关的其他实体一起保存。
@MappedSuperclass
public abstract class BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
BaseEntity() {
}
protected BaseEntity(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
BaseEntity that = (BaseEntity) o;
return id.equals(that.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "auth_type")
public abstract class BlogUser extends BaseEntity {
@ManyToOne
@JoinColumn(name = "user_id", nullable = false, updatable = false)
private User user;
@ManyToOne
@JoinColumn(name = "blog_id", nullable = false, updatable = false)
private Blog blog;
BlogUser() {
}
protected BlogUser(User user, Blog blog) {
this.user = user;
this.blog = blog;
}
public User getUser() {
return user;
}
public Blog getBlog() {
return blog;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof BlogUser)) return false;
BlogUser blogUser = (BlogUser) o;
return user.equals(blogUser.getUser()) && blog.equals(blogUser.getBlog());
}
@Override
public int hashCode() {
return Objects.hash(user, blog);
}
}
@Entity
@DiscriminatorValue("ADMIN")
public class BlogAdmin extends BlogUser {
public BlogAdmin(User user, Blog blog) {
super(user, blog);
}
}
@Entity
@DiscriminatorValue("INVITED")
public class BlogInvitedUser extends BlogUser {
public BlogInvitedUser(User user, Blog blog) {
super(user, blog);
}
}
@Entity
public class Blog extends BaseEntity {
//fields
@OneToMany(mappedBy = "blog", cascade = CascadeType.PERSIST)
private Set<BlogUser> blogUsers = new HashSet<>();
Blog() {
}
public Blog(String name, String introduce) {
this.name = name;
this.introduce = introduce;
}
//other field's getters
public Set<BlogUser> getBlogUsers() {
return blogUsers;
}
public void addBlogUser(BlogUser blogUser) {
if (blogUsers.contains(blogUser)) { // This is not working
throw new DataIntegrityViolationException("blog's users is duplicated");
}
blogUsers.add(blogUser);
}
}
当使用 BlogUser 子实体的博客用户保存博客实体时,博客的 addBlogUser 方法不起作用!
我知道 Set 通过 hashCode 方法工作。所以,我重写了 BlogUser 实体的 hashCode 和 equals 方法。
但是测试结果很奇怪。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ApplicationConfiguration.class, loader = AnnotationConfigContextLoader.class)
public class BlogUserTest {
@Autowired
private UserDao userDao;
@Autowired
private BlogDao blogDao;
@Test
@Transactional
public void WhenAddBlogUsers_GivenDifferntTypeSameUserAndBlogAfterPersistBlog_ThrowDataIntegrityViolationException() {
User user = new User("name", "nick", "email", null);
userDao.save(user);
Blog blog = new Blog("test", null);
BlogUser admin = new BlogAdmin(user, blog);
blog.addBlogUser(admin);
blogDao.save(blog);
System.out.println(blog.getBlogUsers().iterator().next().hashCode() == new BlogInvitedUser(user, blog).hashCode()); // true
System.out.println(blog.getBlogUsers().contains(new BlogInvitedUser(user, blog))); // false
}
}
事实上,在测试时,我知道如果 EntityManager 坚持下去,它就可以工作。
我想知道内部发生了什么。
欢迎任何答案。
解决方案
推荐阅读
- c# - 如何使用 C# 中的方法在列表中添加数据?我正在尝试添加,但它不能保存数据并且只显示最后一个条目
- java - 带有嵌入式 id 的实体的带有 Spring Boot DDL 查询错误的 Wix 嵌入式 mysql
- jenkins - 基于 git commit 的 Jenkinsfile 管道触发阶段
- android - Android Studio 中导航抽屉预览中的渲染问题
- firebase-realtime-database - 颤动如何使gridview显示像按钮这样的firebase数据
- applescript - 错误:命令失败:osascript -e 告诉应用程序“系统事件”计算名称为“模拟器”的进程 (-1743)
- javascript - 当我按下滚动按钮时,如何限制骰子(3-d 类型)仅滚动三次,并且每次滚动时还需要骰子的值
- ios - 为什么UIDatePicker填充两个不同的TextFields相同的值
- node.js - NPM 安装 404 资源
- arm - HardFault exception (configurable-priority exception to HardFault)