我一直试图了解如何使用hibernate创建一个通用的标签资产库,但我无法让它工作。
我希望它看起来像这样:
我希望订阅和通知共享相同的唯一标记库。
我尝试了@ManyToMany
注释。但我不认为这是做到这一点的方法。在我最好的情况下,我希望Hibernate自动查看标签是否已经存在,然后只使用该ID。但我也可以先创建标签,然后再链接它们。用Hibernate来解决这个问题的最佳方法是什么?
这是我目前的代码:
Subscription.class
@Data
@Entity
public class Subscription {
@Id
@GeneratedValue
@Column(name = "subscription_id")
private Long id;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "subscription_tag",
joinColumns = { @JoinColumn(name = "subscription_id") },
inverseJoinColumns = { @JoinColumn(name = "tag_id") })
private List<Tags> tags = new ArrayList<>();
private String subscriberString;
}
Tags.class
@Data
@Entity
@Table(
name = "notification_tags",
uniqueConstraints = @UniqueConstraint(columnNames = "tag")
)
public class Tags {
@Id
@GeneratedValue
@Column(name = "tag_id")
private Long id;
private String tag;
}
Notification.class
@Data
@Entity(name = "Notification")
@Table(name = "notification")
@TypeDef(
name = "jsonb-node",
typeClass = JsonNodeStringType.class
)
public class Notification extends NotificationBase {
@Id
@GeneratedValue
@Column(name = "notification_id")
private Long id;
// This is when the object was created
private Date updatedTime = new Date();
private Date timestamp;
private String name;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "notification_tag",
joinColumns = { @JoinColumn(name = "notification_id") },
inverseJoinColumns = { @JoinColumn(name = "tag_id") })
private List<Tags> tags = new ArrayList<>();
@Type(type = "jsonb-node")
@Column(columnDefinition = "NVARCHAR(4000)")
private JsonNode customJson;
}
答案 0 :(得分:0)
我还使用@JsonManagedReference
和@JsonBackReference
来避免在序列化为json时进行循环引用。
当我想搜索带有标记的所有订阅时,我不需要搜索所有订阅中的标记,反之亦然,所有包含特定标记的订阅。请参阅下面的代码。
SubscriptionRepository.class (查找具有特定标记的所有订阅)
public interface SubscriptionRepository extends CrudRepository<Subscription, Long>{
List<Subscription> findAllByTag(Tag tag);
}
<强> Subscription.class 强>
@Data
@Entity
public class Subscription {
@Id
@GeneratedValue
@Column(name = "subscription_id")
private Long id;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "subscription_tag",
joinColumns = { @JoinColumn(name = "subscription_id") },
inverseJoinColumns = { @JoinColumn(name = "tag_id") })
private Set<Tags> tags = new HashSet<>();
private String subscriberString;
}
<强> Tag.class 强>
@Data
@Entity
@Table(
name = "notification_tags",
uniqueConstraints = @UniqueConstraint(columnNames = "tag")
)
public class Tag {
@Id
@GeneratedValue
@Column(name = "tag_id")
private Long id;
private String tag;
@ManyToMany(mappedBy = "tags", cascade = { CascadeType.PERSIST, CascadeType.MERGE })
@JsonBackReference
private Set<Subscription> subscriptions = new HashSet<>();
@ManyToMany(mappedBy = "tags", cascade = { CascadeType.PERSIST, CascadeType.MERGE })
@JsonBackReference
private Set<Notification> notifications = new HashSet<>();
public Tag() {
}
@Builder
public Tag(String tag) {
this.tag = tag;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
Tag tag1 = (Tag) o;
return Objects.equals(tag, tag1.tag);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), tag);
}
}
<强> Notification.class 强>
@Data
@Entity(name = "Notification")
@Table(name = "notification")
@TypeDef(
name = "jsonb-node",
typeClass = JsonNodeStringType.class
)
public class Notification extends NotificationBase {
@Id
@GeneratedValue
@Column(name = "notification_id")
private Long id;
// This is when the object was created
private Date updatedTime = new Date();
private Date timestamp;
private String name;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "notification_tag",
joinColumns = { @JoinColumn(name = "notification_id") },
inverseJoinColumns = { @JoinColumn(name = "tag_id") })
private Set<Tags> tags = new HashSet<>();
@Type(type = "jsonb-node")
@Column(columnDefinition = "NVARCHAR(4000)")
private JsonNode customJson;
}