У меня есть объект для отображения исторических данных в системе.
@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;
.
.
.
}
Чтобы избежать огромной исторической таблицы, в базе данных есть триггер для реализации раздела таблицы в зависимости от исторической даты, поэтому существует копия таблицы на каждый месяц.
Когда мне нужно получить данные, мне нужно объединить таблицы в зависимости от предоставленных дат, поэтому система создает запрос такого типа:
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
Я использую createNativeQuery
, чтобы получить результат этого запроса, что-то вроде этого:
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();
}
}
Проблема в том, что он не всегда показывает точно такой же результат, который я получаю, когда выполняю запрос в базе данных, вместо этого иногда результат показывает несколько повторяющихся регистров вместо оригиналов. Однако номер регистра одинаков в обоих случаях.
Для тестов, которые я сделал, кажется, что это начинает происходить, когда количество возвращаемых регистров превышает примерно 4200, так что это может быть проблемой управления памятью. Обратите внимание, что для каждого ElementsHistorical
мне также нужен соответствующий Element
.
Если я не добавляю сущность в запрос и обрабатываю результат как List<Object[]>
, результаты будут хорошими и не отображают эти «поврежденные» регистры, но я не могу использовать этот подход, потому что тогда мне потребуется получить каждый Element
отдельно от каждого ElementsHistorical
, и это было бы ужасно с точки зрения производительности.
Кто-нибудь думает, что это тоже может быть проблемой управления памятью? Как я мог решить это?