Hibernate无限递归和双向关系

时间:2015-07-02 14:57:11

标签: java hibernate jackson

我有两个实体。我想在项目和任务之间建立双向关系。

  • 项目有一个或多个任务
  • 任务仅与一个项目相关联

有我的实体:

ProjectEntity.java

@Entity
@Table(name = "projects")
public class ProjectEntity {
    @Id
    @GeneratedValue
    @Column(name = "pr_id")
    private long id;

    @Column(name = "pr_name", nullable = false)
    private String name;

    @OneToMany(cascade=CascadeType.ALL, mappedBy="project",orphanRemoval=true)
    @JsonBackReference
    private Set<TaskEntity> tasks = new HashSet<TaskEntity>();

   // Getters, constructors, setters

TaskEntity.java

@Entity
@Table(name = "tasks")
public class TaskEntity {
    @Id
    @GeneratedValue
    @Column(name = "ta_id")
    private long id;

    @Column(name = "ta_name")
    private String name;

    @ManyToOne
    @JoinColumn(name="pr_id")
    @JsonManagedReference
    private ProjectEntity project;

    // Getters, constructors, setters

我希望每个ProjectEntity和每个TaskEntity项目中的任务列表都相关联。

在这里,我使用@JsonManagedReference@JsonBackReference来停止它生成的无限递归,但在我的ProjectEntity中,我没有任务列表(因为{ {1}})......

你能帮助我找回@JsonBackReference中的任务列表吗?我听说过ProjectEntity,但我还没有这么做。

希望我能理解:)

2 个答案:

答案 0 :(得分:2)

我知道的解决方案实际上是在使用&#39; @JsonIdentityInfo&#39;代替&#39; @JsonBackReference&#39;和&#39; @JsonManagedReference&#39;。 您必须删除&#39; @ JsonBackReference&#39;和&#39; @JsonManagedReference&#39;使用&#39; @JsonIdentityInfo&#39;。

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property="id")
@Entity
@Table(name = "projects")
public class ProjectEntity {
    @Id
    @GeneratedValue
    @Column(name = "pr_id")
    private long id;

    @Column(name = "pr_name", nullable = false)
    private String name;

    @OneToMany(cascade=CascadeType.ALL, mappedBy="project",orphanRemoval=true)
    private Set<TaskEntity> tasks = new HashSet<TaskEntity>();
}


@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property="id")
@Entity
@Table(name = "tasks")
public class TaskEntity {
    @Id
    @GeneratedValue
    @Column(name = "ta_id")
    private long id;

    @Column(name = "ta_name")
    private String name;

    @ManyToOne
    @JoinColumn(name="pr_id")
    private ProjectEntity project;
}

答案 1 :(得分:1)

您可以选择为ProjectEntity.tasks列表实现自定义序列化程序。但是你必须在某个时候控制/停止序列化循环;这取决于您的要求。 这是我的意思的一个例子。

@Entity
@Table(name = "projects")
public class ProjectEntity {
    ...
    @OneToMany(cascade=CascadeType.ALL, mappedBy="project", orphanRemoval=true)
    @JsonSerialize(using = CustomListSerializer.class)
    private Set<TaskEntity> tasks = new HashSet<TaskEntity>();
}

CustomListSerializer可能是这样的,

public class CustomListSerializer extends JsonSerializer<List<TaskEntity>>{

    @Override
    public void serialize(List<TaskEntity> tasks, JsonGenerator generator, SerializerProvider provider)
          throws IOException, JsonProcessingException {

        generator.writeStartArray();

        for (TaskEntity task : tasks) {
            generator.writeStartObject("taskEntity")
                .write("id", task.id)
                .write("name", task.name)
                .write("project", task.project.id) //<- here you stop the cycle 
            .writeEnd();
        }
        generator.writeEnd();
    }
}

请注意,它基本上是mentioned mini guide的示例,但它序列化了项目任务列表元素的信息,而不是任务&#39;仅限id。