Hibernate用户和朋友JsonReference

我有两个表:Users和User_Friend用于显示与添加字段的关系。

CREATE TABLE public.users ( uuid VARCHAR(36) PRIMARY KEY NOT NULL, username VARCHAR(45) UNIQUE NOT NULL, first_name VARCHAR(255) NOT NULL, last_name VARCHAR(255), middle_name VARCHAR(255) ); CREATE TABLE public.user_friends ( uuid VARCHAR(36) PRIMARY KEY, user_uuid VARCHAR(36) REFERENCES public.users (uuid) NOT NULL, friend_uuid VARCHAR(36) REFERENCES public.users (uuid) NOT NULL, friendAddDate TIMESTAMP NOT NULL, friendTypeId INT NOT NULL, CONSTRAINT friend_unique UNIQUE (user_uuid, friend_uuid) ); 

具有hibernate注释的Java实体:

 @Entity @Table(name = "users") public class User implements Serializable { @Id @GeneratedValue(generator = "system-uuid", strategy = GenerationType.IDENTITY) @GenericGenerator(name = "system-uuid", strategy = "uuid2") @Column(name = "uuid", unique = true) protected String uuid; @Column(name = "username") protected String username; @JsonManagedReference @OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) private Set userFriends = new HashSet(); @JsonManagedReference @OneToMany(fetch = FetchType.LAZY, mappedBy = "friendUser", cascade = CascadeType.ALL, orphanRemoval = true) private Set userFriendOf = new HashSet(); } @Entity @Table(name = "user_friends") @AssociationOverrides({ @AssociationOverride(name = "user", joinColumns = @JoinColumn(name = "user_uuid")), @AssociationOverride(name = "friendUser", joinColumns = @JoinColumn(name = "friend_uuid")) }) public class UserFriend implements Serializable { @Id @GeneratedValue(generator = "system-uuid") @GenericGenerator(name = "system-uuid", strategy = "uuid2") @Column(name = "uuid", unique = true) protected String uuid; @JsonBackReference @ManyToOne(optional = false) @JoinColumn(name="user_uuid") private User user; @JsonBackReference @ManyToOne(optional = false) @JoinColumn(name="user_uuid") private User friendUser; @Column(name = "friendadddate") protected Date friendAddDate; @Column(name = "friendtypeid") protected int friendTypeId; } 

我正在尝试解决递归问题,同时反序列化为JSON我将@JsonManagedReference添加到User类的userFriends和userFriendOf以及@JsonBackReference添加到UserFriend类的user和friendUser实体,现在在JSP上的JSON中我没有字段也没有friendUser也不是用户。

但在这种情况下 – 如果没有在JSON类中设置friendsOf,我可以使用UserFriend类的用户friendUser。

 @Entity @Table(name = "users") public class User implements Serializable { @Id @GeneratedValue(generator = "system-uuid", strategy = GenerationType.IDENTITY) @GenericGenerator(name = "system-uuid", strategy = "uuid2") @Column(name = "uuid", unique = true) protected String uuid; @Column(name = "username") protected String username; @JsonManagedReference @OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) private Set userFriends = new HashSet(); } @Entity @Table(name = "user_friends") @AssociationOverrides({ @AssociationOverride(name = "user", joinColumns = @JoinColumn(name = "user_uuid")), @AssociationOverride(name = "friendUser", joinColumns = @JoinColumn(name = "friend_uuid")) }) public class UserFriend implements Serializable { @Id @GeneratedValue(generator = "system-uuid") @GenericGenerator(name = "system-uuid", strategy = "uuid2") @Column(name = "uuid", unique = true) protected String uuid; @JsonBackReference @ManyToOne(optional = false) @JoinColumn(name="user_uuid") private User user; @ManyToOne(optional = false) @JoinColumn(name="user_uuid") private User friendUser; @Column(name = "friendadddate") protected Date friendAddDate; @Column(name = "friendtypeid") protected int friendTypeId; } 

所以我的问题是我需要做什么才能在所有用户类集中获得friendUser和user?

更新进度:我正在google搜索有关我的问题的信息,并连续两天在谷歌第一(第二)链接 – 这个问题… ;-)我仍然无法用jsonreference模式解决我的问题。 我开始考虑改变数据库的架构。

我做的。 再次。 StackOverFlow给了我更多的动力而不是问题:D

因此,经过3个漫长的一天思考我的问题,我几乎拒绝反序列化到json并做出决定不要在这种情况下使用json,但是我想到了类的jsonidentity,这是我的解决方案。

使用JsonIdentityInfo,每次Jackson序列化你的对象时,它都会添加一个id(在我的例子中是uuid),因此它不会再次扫描它。

更新ASNWER(为了缩短答案,我删除了代码的先前版本的答案):不幸的是,当我在不同情况下测试我的解决方案时,我发现,它只适用于第一版json身份。 因此,首先“扫描”完全像魅力一样工作,但是第二次扫描我获得了jsonidentity而不是对象的ID。 这让我理解,我需要自己的序列化逻辑,我可以控制递归的深度。 我写了它。 我只能显示自定义json序列化器的骨架,因为序列化的逻辑很容易并且依赖于类结构。

 public class JsonUserSerializer extends JsonSerializer { @Override public void serialize(User o, JsonGenerator jsonGen, SerializerProvider serializerProvider) throws IOException, JsonProcessingException { // ... logic of json generation Field[] userClassFields = o.getClass().getDeclaredFields(); // ... logic of json generation } @Override public Class handledType() { return User.class; } } 

在处理代码时我必须解决的主要问题是字段的命名。 因为json结构是:“name”:“value” – 在我的情况下名称 – 它是fieldName。 但硬编码不是我的方式。 比我找到解决方案来获取类的所有字段,它是o.getClass().getDeclaredFields()而不是按索引查找需求字段。 我认为这不是最好的解决方案,但我没有找到其他一小时(如果你知道其他方式 – 写评论 – 我会赞扬作者)。

忘记显示如何使用为特定类指定的自定义JsonSerialiser:

 @Entity @Table(name = "users") @JsonSerialize(using = JsonUserSerializer.class) public class User implements Serializable { // a lot of fields and getter, and setters }