0

I have the following classes:

@Entity
@Table(name = "elements")
@Inheritance(strategy=InheritanceType.JOINED)
@XmlRootElement
public abstract class Elements implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "idelement")
    private Integer idElement;

    @Basic(optional = false)
    @Column(name = "code")
    private String code;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "idElement")
    @Fetch(value = FetchMode.SUBSELECT)
    private Collection<Alarms> alarmsCollection;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "idElement")
    @Fetch(value = FetchMode.SUBSELECT)
    private Collection<ElementsHistorical> elementsHistoricalCollection;   

    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST, mappedBy = "elementsCollection")
    @Fetch(value = FetchMode.SUBSELECT)
    private Collection<ElementsGroups> elementsGroupsCollection;


    //Constructors, getters and setters
}

@Entity
@Table(name = "alarms")
@XmlRootElement(name = "Alarms")
public class Alarms implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "idalarm")
    private Integer idAlarm;

    @JoinColumn(name = "idelement", referencedColumnName = "idelement")
    @ManyToOne(optional = false)
    private Elements idElement;

    //Constructors, getters and setters

}

I created a jersey webservice and a DAO class with CRUD operations to treat Alarms data. With this implementation, when I call GET method, I get the whole Elements object inside the Alarms one. This is the DAO method called:

public List<Alarms> getAlarms(){
    Session session = SessionUtil.getSession();    
    Query query = session.createQuery("from Alarms");
    List<Alarms> alarms =  query.list();
    session.close();
    return alarms;
}

I don't want this fetch = FetchType.EAGER fetch type, as I just need the PK of Elements, but after some research this is the only way I found to make my service work. I tried this and this approach, but I've not been able to make it work.

Community
  • 1
  • 1
Juan
  • 1,949
  • 1
  • 15
  • 22

3 Answers3

0

You can use left outer join fetch in you query.

Query query = session.createQuery("from Alarms alarm left outer join fetch alarm.idElement element");

Now you can keep fetch = FetchType.LAZY (which is default).

Mehmood Memon
  • 1,129
  • 2
  • 12
  • 20
0

Try to add @XmlTransient annotation to fields in Elements class that you want to ignore. like this :

@Entity
@Table(name = "elements")
@Inheritance(strategy=InheritanceType.JOINED)
@XmlRootElement
public abstract class Elements implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "idelement")
    private Integer idElement;

    @Basic(optional = false)
    @Column(name = "code")
    @XmlTransient
    private String code;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "idElement")
    @Fetch(value = FetchMode.SUBSELECT)
    @XmlTransient
    private Collection<Alarms> alarmsCollection;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "idElement")
    @Fetch(value = FetchMode.SUBSELECT)
    @XmlTransient
    private Collection<ElementsHistorical> elementsHistoricalCollection;   

    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST, mappedBy = "elementsCollection")
    @Fetch(value = FetchMode.SUBSELECT)
    @XmlTransient
    private Collection<ElementsGroups> elementsGroupsCollection;


    //Constructors, getters and setters
}
0

You can use multiselect with Tuple, for select only specific columns.

    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<Tuple> cq = cb.createTupleQuery();
    Root<Alarms> root = cq.from(Alarms.class);
    CollectionJoin<Object, Object> joinCollection = root.joinCollection("alarmsCollection");
    cq.multiselect(joinCollection.get("idElement"));
    List<Tuple> tupleResult = entityManager.createQuery(cq).getResultList();
    for (Tuple t : tupleResult) {
        Long idElement = (Long) t.get(0);
    }
jklee
  • 2,198
  • 2
  • 15
  • 25