неуправляемые объекты jpa

Допустим, мне нужно запустить такой запрос:

Select primarykey, columnname, old_value, new_value from first_audit_log;

Select primarykey, columnname, old_value, new_value from second_audit_log;

Select primarykey, columnname, old_value, new_value from third_audit_log; ...so on

audit_log не сопоставляется как сущность JPA с каким-либо классом, и я строго не могу создать n количество классов для n количества *_audit_logs.

Используя встроенную функцию запросов, как лучше всего сопоставить это с общим классом? Пытаюсь ВЫБРАТЬ НОВУЮ функцию, но не уверен... Поэтому любая помощь приветствуется.


person user1224036    schedule 05.03.2013    source источник
comment
Какой поставщик постоянства вы используете? В Eclipselink есть подсказка ResultType, которая может помочь eclipse.org /eclipselink/api/2.2/org/eclipse/persistence/config/   -  person rootkit    schedule 05.03.2013


Ответы (2)


Поскольку в таблицах журналов аудита используются одни и те же столбцы, вы можете создать представление, которое «объединяет» эти таблицы, и сопоставить один класс Java с этим представлением. Я считаю, что вы можете, так как вам не нужно писать обновления, я думаю.

В качестве альтернативы хорошим выбором будет использование нативных запросов.

ИЗМЕНИТЬ:

1) Если ваши журналы аудита являются уже представлениями, вы можете создать представление на основе других представлений, если вы не хотите создавать сопоставленный класс Java для каждого из них. Просто не забудьте добавить фиктивный столбец со значением 1, если строка исходит из «первого» журнала аудита, 2, если она исходит из второго, и т. д., чтобы вы могли различать их.

2) Чтобы использовать собственные запросы, предполагая, что вашим поставщиком постоянства является Hibernate, вы можете сделать, как в этом примере:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("test");
EntityManager em = emf.createEntityManager();

Session sess = em.unwrap(Session.class); // <-- Use Hibernate-specific features
SQLQuery query = sess.createSQLQuery(
   "SELECT AVG(age) AS averageAge, AVG(salary) as averageSalary FROM persons");

query.setResultTransformer(Transformers.aliasToBean(MyResult.class));
MyResult result = (MyResult) query.list().get(0);

где MyResult объявляется следующим образом:

public class MyResult {

    private BigDecimal averageAge;
    private BigDecimal averageSalary;

    public BigDecimal getAverageAge() {
        return averageAge;
    }
    public void setAverageAge(BigDecimal averageAge) {
        this.averageAge = averageAge;
    }
    public BigDecimal getAverageSalary() {
        return averageSalary;
    }
    public void setAverageSalary(BigDecimal averageSalary) {
        this.averageSalary = averageSalary;
    }

}

а таблица persons выглядит так (синтаксис MySQL):

CREATE TABLE `persons` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `firstname` varchar(255) NOT NULL,
  `lastname` varchar(255) NOT NULL,
  `age` int(11) NOT NULL,
  `salary` int(11) NOT NULL,
  PRIMARY KEY (`id`)
);

Вы можете легко адаптировать этот пример под свои нужды, просто замените persons и MyResult на то, что вам нужно.

person gd1    schedule 05.03.2013
comment
нет ... журналы аудита уже являются представлениями ... как сопоставить общий класс с использованием собственных запросов? ... я хотел бы избежать путей Object [] - person user1224036; 05.03.2013
comment
ваш второй вариант лучше, но вам нужно знать, как сопоставить пользовательский класс - person user1224036; 05.03.2013
comment
Почему бы вам не попробовать сопоставить один из ваших пользовательских классов? Документы не говорят, что resultClass должен управляться. - person gd1; 05.03.2013
comment
Я был неправ. Я обновил свой ответ: это единственный способ сделать это с помощью Hibernate. - person gd1; 05.03.2013

Псевдонимы в запросе sql автоматически преобразуются в верхний регистр, и он ищет установщик в верхнем регистре, в результате чего возникает исключение org.hibernate.PropertyNotFoundException. Любые предложения будут ценны.

Например, приведенный ниже оператор ищет идентификатор установщика вместо идентификатора/идентификатора (не удалось найти установщик для идентификатора в данных класса)

List<Data> result = entityManager.unwrap(Session.class) 
            .createSQLQuery("Select id as id from table") 
            .setParameter("day", date.getDayOfMonth()) 
            .setParameter("month", date.getMonthOfYear()) 
            .setParameter("year", date.getYear()) 
           .setResultTransformer(Transformers.aliasToBean(Data.class))
           .list();

class Data {
  Integer id;

  public Integer getId() {
    return id;
  }

  public void setId(Integer id) {
   this.id = id;
  }
}
person Minisha    schedule 24.11.2015
comment
Принудительное использование чувствительности к регистру сработало для меня... Я нашел ответ по следующей ссылке stackoverflow.com/questions/8136225/ - person Minisha; 24.11.2015
comment
У меня есть еще один вопрос, что произойдет с сеансом после этой строки: entityManager.unwrap(Session.class)? Будет ли сеанс закрыт автоматически или нам придется закрыть сеанс явно? - person Minisha; 24.11.2015