-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Limit results in a Collection in a OneToMany relationship
PostPosted: Wed May 15, 2013 12:02 pm 
Newbie

Joined: Tue May 14, 2013 9:36 am
Posts: 3
I have a scenario in which I'd like to limit the amount of data retreived within the Collection returned when retrieving a class containing a OneToMany relationship. Here is an example scenario. I have a person and want to track their location over time. The number of locations for a person is going to grow quite large. I will not want to get every single location from that person every time I get a person object. But, I will want to know the last known location or maybe even the last n locations when I get the person object. Is there a way to acheive this through the annotations?

I have seen documentation and discussions that suggest a unidirectional ManyToOne mapping and use queries to retrieve the position data. But, I don't completely understand that statement. I want the user of the Person class to be able to call the getPostions method. And, I'm not sure how to acheive this with a ManyToOne unidrectional mapping.

Here is an example mapping:

Code:

@Entity
@Table( name="person")
public class Person
{
    ...

    @OneToMany(mappedBy="person", targetEntity=Position.class,
               fetch=FetchType.EAGER, cascade = CascadeType.ALL)
    public List<Position> getDetections() { return this.positions; }
    public void setDetections( List<Position> positions )
    {
        this.positions = positions;
    }
   
    ...
    private List<Position> positions = new ArrayList<Position>();
}

@Entity
@Table( name="position")
public class Position
{
    ...
   
    @ManyToOne(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
    @JoinColumn(name="person_id", nullable=false)
    public Person getPerson() { return this.person; }
    public void setPerson( Person person ) { this.person = person; }   

    ...
    private Person person;
}



Top
 Profile  
 
 Post subject: Re: Limit results in a Collection in a OneToMany relationship
PostPosted: Wed May 15, 2013 5:25 pm 
Newbie

Joined: Tue May 14, 2013 9:36 am
Posts: 3
OK, I figured it out after lots of digging online. There are two ways of doing this that I now know of. One using the @Where annotation and the other using the @FilterDef/@Filter annotations. I find the @Filter annotations to be the more elegant solution as I can program in the number of latest entries I want returned. The first code segment will be how to do this with the @Where annotation and the second will be with the @Filter annotations:

Code:
@Entity
@Table( name="person")
public class Person
{
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="personid_gen")
    @SequenceGenerator(name="personid_gen",sequenceName="personid_seq",
                       allocationSize=1 )
    @Column(name="person_id", nullable=false)
    public Integer getID() { return this.id; }
    public void setID( Integer id ) { this.id = id; }
   
    @Column( name="name", length=50 )
    public String getName() { return this.name; }
    public void setName( final String name ) { this.name = name; }
   
    @OneToMany(mappedBy="person", targetEntity=Position.class,
               fetch=FetchType.EAGER, cascade = CascadeType.ALL)
    @Where(clause="postion_id = (select max(p.postion_id) from position p where p.person_id = person_id)")   
    public List<Position> getDetections() { return this.positions; }
    public void setDetections( List<Position> positions )
    {
        this.positions = positions;
    }
   
    private Integer id;
    private String name;
    private List<Position> positions = new ArrayList<Position>();
}

@Entity
@Table( name="position")
public class Position
{
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="positionid_gen")
    @SequenceGenerator(name="positionid_gen",sequenceName="positionid_seq",
                       allocationSize=1 )
    @Column(name="position_id", nullable=false)
    public Integer getID() { return this.id; }
    public void setID( Integer id ) { this.id = id; }   
   
    @ManyToOne(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
    @JoinColumn(name="person_id", nullable=false)
    public Person getPerson() { return this.person; }
    public void setPerson( Person person ) { this.person = person; }   
   
    @Column( name="time_recorded")     
    public Long getUpdateTime() { return this.time; }
    public void setUpdateTime( final Long time ) { this.time = time; }   
   
    @Column( name="latitude")     
    public Float getLatitude() { return latitude; }
    public void setLatitude( final Float latitude )
    {
        this.latitude = latitude;
    }
   
    @Column( name="longitude")     
    public Float getLongitude() { return longitude; }
    public void setLongitude( final Float longitude )
    {
        this.longitude = longitude;
    }
   
    private Integer id;
    private Long time;
    private Float latitude;
    private Float longitude;
    private Person person;
}


Here it is using the @Filter annotations:

Code:
@Entity
@FilterDef(name="numRecordsFilter", parameters=@ParamDef( name="numRecords", type="integer" ) )
@Table( name="person")
public class Person
{
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="personid_gen")
    @SequenceGenerator(name="personid_gen",sequenceName="personid_seq",
                       allocationSize=1 )
    @Column(name="person_id", nullable=false)
    public Integer getID() { return this.id; }
    public void setID( Integer id ) { this.id = id; }
   
    @Column( name="name", length=50 )
    public String getName() { return this.name; }
    public void setName( final String name ) { this.name = name; }
   
    @OneToMany(mappedBy="person", targetEntity=Position.class,
               fetch=FetchType.EAGER, cascade = CascadeType.ALL)
    @Filter(name="numRecordsFilter", condition="postion_id > (select max(p.postion_id) from position p where p.person_id = person_id) - :numRecords")   
    @Where(clause="postion_id = (select max(p.postion_id) from position p where p.person_id = person_id)")   
    public List<Position> getDetections() { return this.positions; }
    public void setDetections( List<Position> positions )
    {
        this.positions = positions;
    }
   
    private Integer id;
    private String name;
    private List<Position> positions = new ArrayList<Position>();
}

@Entity
@Table( name="position")
public class Position
{
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="positionid_gen")
    @SequenceGenerator(name="positionid_gen",sequenceName="positionid_seq",
                       allocationSize=1 )
    @Column(name="position_id", nullable=false)
    public Integer getID() { return this.id; }
    public void setID( Integer id ) { this.id = id; }   
   
    @ManyToOne(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
    @JoinColumn(name="person_id", nullable=false)
    public Person getPerson() { return this.person; }
    public void setPerson( Person person ) { this.person = person; }   
   
    @Column( name="time_recorded")     
    public Long getUpdateTime() { return this.time; }
    public void setUpdateTime( final Long time ) { this.time = time; }   
   
    @Column( name="latitude")     
    public Float getLatitude() { return latitude; }
    public void setLatitude( final Float latitude )
    {
        this.latitude = latitude;
    }
   
    @Column( name="longitude")     
    public Float getLongitude() { return longitude; }
    public void setLongitude( final Float longitude )
    {
        this.longitude = longitude;
    }
   
    private Integer id;
    private Long time;
    private Float latitude;
    private Float longitude;
    private Person person;
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.