Hibernate关联映射

时间:2015-09-01 18:59:45

标签: json spring hibernate

enter image description here我有两个类:Event和User。每个“事件”仅由一个“用户”创建,但“用户”可以创建许多“事件”。我创建了这样的关系:

@Entity
@Table(name="events")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Event {

    @Id @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;

    @NotBlank
    private String name;

    @NotBlank
    @Type(type="text")
    private String description;

    private String event_type;

    @NotNull
    @Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
    private LocalDateTime expected_start;

    @Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
    private LocalDateTime expected_end;

    @Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
    private LocalDateTime actual_start;

    @Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
    private LocalDateTime actual_end;

    @NotBlank
    private String environment;

    private int executed_by;

    @Temporal(TemporalType.TIMESTAMP)
    @CreationTimestamp
    private Date created_at;

    @Temporal(TemporalType.TIMESTAMP)
    @UpdateTimestamp
    private Date updated_at;

    @ManyToOne
    @JoinColumn(name="created_by")
    private User creator;

}

@Entity
@Table(name="users")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "username")
@FieldMatch(first = "password", second = "repassword",message = "The password fields must match")
public class User{

    @Id
    @NotBlank
    @Size(min=5,max=15)
    @Column(name="username", unique=true)
    private String username;

    @NotBlank
    private String first_name;
    @NotBlank
    private String last_name;
    @NotBlank
    private String password;

    @NotBlank
    @Transient
    private String repassword;
    @NotBlank
    private String email;
    @NotBlank
    private String phone;

    @Temporal(TemporalType.TIMESTAMP)
    @CreationTimestamp
    private Date created_at;

    @Temporal(TemporalType.TIMESTAMP)
    @UpdateTimestamp
    private Date updated_at;

    @OneToMany(mappedBy="creator")
    private Collection<Event> events=new ArrayList<Event>();
}

DAO:

public List<Event> getEvents() {

        Criteria criteria=getCurrentSession().createCriteria(Event.class);
        return (List<Event>) criteria.list();
    }

我使用jackson转换为JSON。当为特定事件进行ajax调用时,它会随之提取用户信息。这是好的,因为它需要我。但由于用户类中的@oneToMany,它还会拉动用户创建的其他事件。如何克服这个

1 个答案:

答案 0 :(得分:1)

我猜杰克逊在序列化时会检查events集合大小,因为你使用的是openSessionInViewFilter,所以集合会被提取,所以它会把它放在响应中。您只需@JsonIgnore events字段。

设计说明: 我认为&#34;开放会议在视野中#34;是一种反模式。任何事务管理都应该在视图层之下进行。为了将视图层与下面的层分离,您应该将DTO返回到视图层而不是JPA实体。除非您正在做一些玩具项目,否则您所获得的投资并不后悔。

我是怎么做到的:

  • 我使用JPA的select new机制来编写专用查询
  • 使查询类型安全我使用QueryDSL(但这是可选的,你可以先试用普通的JPQL)
  • 查询返回甚至不需要杰克逊注释的DTO对象,因为它们代表我想要在视图中获得的内容。

这种方法的另一个优点是比JPA的正常实体加载快得多。有些人更喜欢加载实体然后重新打包它们,这样可以节省编写查询所需的工作量(一旦你得到它的工作方式就很小)但是没有性能上的好处。