2013-03-05 3 views
4

Допустим, у меня есть огнь запроса, как это: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 enity к любому классу, и я категорически не могу создавать n количества классов для n числа *_audit_logs.

Использование встроенной функции запросов, как наилучшим образом я могу сопоставить это с общим классом? Попытка выбрать функцию SELECT NEW, но не уверен ... Поэтому любая помощь приветствуется.

+0

Что живучесть поставщик, который вы используете? Eclipselink имеет подсказку ResultType, которая могла бы помочь http://www.eclipse.org/eclipselink/api/2.2/org/eclipse/persistence/config/ResultType.html – rootkit

ответ

3

Поскольку ваши таблицы журналов аудита имеют одни и те же столбцы, вы можете создать представление, которое «унифицирует» эти таблицы и сопоставляет один класс Java для этого представления. Думаю, вы можете, так как вам не нужно писать обновления, я думаю.

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

EDIT:

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 тем, что вы хотите.

+0

no ..auditlogs уже просматриваются ... как сопоставить с общим класс с использованием собственных запросов? ... я хотел бы избегать Object [] путей – user1224036

+0

любых предложений? – user1224036

+0

спасибо, я посмотрю – user1224036

1

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

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

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; 
    } 
} 
+1

Принудительная чувствительность к регистру с использованием «» работала для меня ... Я нашел ответ в следующей ссылке http://stackoverflow.com/questions/8136225/resulttransformer-with-createsqlquery-forces- no-camelcase-in-entity-fields – Minisha

+0

У меня есть другой вопрос, что произойдет с сеансом после этой строки: entityManager.unwrap (Session.class)? Закрывается ли сессия автоматически или мы должны явно закрыть сеанс? – Minisha