0

Problem Statement: Country have collection relationship with State. Fetching a country getting all its states associated with it. It is desired in many cases. Now in a given case,I have both country id and state id, and when fetch country filtering with state id, is it possible to get single State in Country?

Country.class

@Entity
@Repository
@Table(name="COUNTRY")
class Country implements Serializable{

@Id
@GeneratedValue(startegy=GenerationType.AUTO)
private long id;

@OneToMany(mappedBy="country", cascade={javax.persistence.CascadeType.ALL}, fetch=FetchType.EAGER)
private java.util.Set<State> states;
//Getters and setters


}

State.class

@Entity
@Repository
@Table(name="STATE")
class State implements Serializable{

@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="id", nullable=false, unique=true, updatable=true)
private long @Id

@ManyToOne
@JoinColumn(name="id")
private Country country;

//Getter and setter
}

I have tried with following query:

//This query works great when used in SQL editor. Getting one state     
select * from country left join state  ON country.id = state.id and state.id=3 
//Tried following
    setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)

Used above SQL query and created criteria, but I am getting all states. Or this problem can be solved? Do we have better alternatives?

Vish
  • 832
  • 7
  • 21

1 Answers1

1

That's not how JPA is intended to work. It would cause problems with tracking entity changes (JPA provider might think that missing states are removed from the collection).

However, Hibernate supports this by using @Filter and @FilterDef, take a look at this thread. Here is the code used in the example:

@Entity
public class A implements Serializable{
    @Id
    @Column(name = "REF")
    private int ref;

    @OneToMany
    @JoinColumn(name = "A_REF", referencedColumnName = "REF")   
    @Filter(name="test")
    private Set<B> bs;
}

@Entity
@FilterDef(name="test", defaultCondition="other = 123")
public class B implements Serializable{
    @Id
    @Column(name = "A_REF")
    private int aRef;

    @Id
    @Column(name = "OTHER")
    private int other;
}

Session session = entityManager.unwrap(Session.class);
session.enableFilter("test");
A a = entityManager.find(A.class, new Integer(0))
a.getb().size() //Only contains b that are equals to 123
Community
  • 1
  • 1
Predrag Maric
  • 23,938
  • 5
  • 52
  • 68