lch
lch

Reputation: 4931

Hibernate association mappings

enter image description hereI have two classes: Event and User. Every 'event' is created by only one 'user', but a 'user' can create many 'events'. I created relationships like this:

@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();
    }

I am using jackson for converting to JSON. when make an ajax call for a particular event, it pull the user information along with it. that's OK as it is need for me. But it also pull's other events created by user because of @oneToMany in user class. How to overcome this

Upvotes: 0

Views: 100

Answers (1)

MirMasej
MirMasej

Reputation: 1622

I guess that Jackson, while serializing, checks the events collection size and, since you are using openSessionInViewFilter, the collection gets fetched, so it puts it in the response. You can just @JsonIgnore the events field.

Design note: I think that "Open session in view" is an anti-pattern. Any transaction management should be done a level below the view layer. In order to decouple view layer from the layers below you should be returning DTOs to the view layer instead of JPA entities. Unless you're doing some toy project, that's the investment you won't regret.

How I do it:

  • I use select new mechanism from JPA to write dedicated query
  • to make queries typesafe I use QueryDSL (but that's optional, you can try out an ordinary JPQL first)
  • queries return DTO objects that don't even need Jackson annotations as they represent what I want to get in the view.

This approach has additional advantage of being much faster than normal entity loading by JPA. Some prefer loading entities and then repackage them which saves effort required to write the query (which is minimal once you get it how it works) but then there is no performance benefit.

Upvotes: 1

Related Questions