有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Hibernate用户和朋友JsonReference

我有两个表:Users和User\u 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<UserFriend> userFriends = new HashSet<>();

@JsonManagedReference
@OneToMany(fetch = FetchType.LAZY, mappedBy = "friendUser", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<UserFriend> 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添加到用户类的userFriends和userFriendOf集合中,并将@JsonBackReference添加到UserFriend类的User和friendUser实体中,现在在JSP上的JSON中,我没有字段,也没有friendUser或User

但在这种情况下,如果不在JSON中设置类内用户的friendsOf,我可以设置UserFriend类的用户FriendsUser

@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<UserFriend> 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

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


共 (1) 个答案

  1. # 1 楼答案

    我做到了。再一次StackOverFlow给了我比问题更多的动力:D

    所以,在每小时思考我的问题三天之后,我几乎拒绝反序列化到json,并决定在这种情况下不使用json,但我会考虑类的jsonidentity,这是我的解决方案

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

    更新ASNWER(我删除了之前版本的代码,以简化答案): 不幸的是,当我在不同的情况下测试我的解决方案时,我发现它只适用于json标识的第一个版本。所以,第一次“扫描”就像一个符咒,但第二次扫描我得到的是一个jsonidentity的ID,而不是object。这让我明白,我需要自己的序列化逻辑,在这里我可以控制递归的深度。是我写的。我只能展示自定义json序列化程序的框架,因为序列化的逻辑很简单,并且取决于类结构

    public class JsonUserSerializer extends JsonSerializer<User> {
            @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<User> handledType() {
                return User.class;
            }
        }
    

    在编写代码时,我必须解决的主要问题是字段的命名。因为json结构是:“name”:“value”——在我的例子中是name——它是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
    }