I have an entity to map historic data on a system.
@Entity
@Table(name = "historicsview")
@XmlRootElement
public class ElementsHistorical implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "historicalid")
private Long historicalId;
@Basic(optional = false)
@Column(name = "historicdate")
private Date historicDate;
@Basic(optional = false)
@Column(name = "value")
private double value;
@Basic(optional = false)
@Column(name = "code")
private int code;
@Basic(optional = false)
@Column(name = "subtype")
private int subType;
@Basic(optional = false)
@Column(name = "subcode")
private int subCode;
@Basic(optional = false)
@Column(name = "uniquecode", unique=true)
private String uniqueCode;
@JoinColumn(name = "elementid", referencedColumnName = "elementid")
@ManyToOne(optional = false)
private Elements element;
.
.
.
}
To avoid a huge historic table, there's a trigger in database for implementing the table partition depending on historic date, so there's a copy of the table for every month. When I need to obtain the data, I need to join the tables depending on the dates provided, so the system creates a query of this kind:
select * from
(select * from elementshistorical_201905
where historicdate >= TO_TIMESTAMP('20190502 00:00:00', 'yyyyMMdd hh24:mi:ss')
union
select * from demeter.elementshistorical_201906 where historicdate <= TO_TIMESTAMP('20190606 23:59:59', 'yyyyMMdd hh24:mi:ss'))
as foo where ((subcode=2 and (subtype=2 or subtype=8)) or code=100) and elementid in (16290)
order by historicdate asc
I use createNativeQuery
to obtain the result of this query, something like this:
public List<ElementsHistorical> executeSqlQueryHistory(String query) {
Session session = null;
List<ElementsHistorical> result;
try {
session = SessionUtil.getSession();
result = session.createNativeQuery(query).addEntity(ElementsHistorical.class).getResultList();
return result;
}catch(Exception e) {
e.printStackTrace();
return null;
}finally {
session.clear();
session.close();
}
}
The problem with this is it doesn't always show exactly the same result that I get when I execute the query in database, instead, sometimes the result shows some repeated registers instead of the originals. However, the number of register is the same in both cases.
For the tests I made, it seems that this starts to happen when the number of returned registers exceed about 4200, so this could be a memory management problem. Notice that for every ElementsHistorical
, I need the related Element
too.
If I don't add the entity to the query and I treat the result as a List<Object[]>
, the results are fine and doesn't show this "corrupted" registers, but I can't use this approach because then I would need to get every Element
individually from each ElementsHistorical
, and that would be terrible in terms of performance.
Anyone thinks that this could be a memory management problem too? How could I solve this?