Ошибка «Не найдено постоянных классов для класса запроса» при попытке создания объекта map с использованием HQL

#java #spring #spring-boot #hibernate #hql

#java #spring #весенняя загрузка #переход в спящий режим #hql

Вопрос:

Я хотел бы сопоставить пользовательский объект непосредственно из базы данных ( ApplicationStatus в Status ), используя метод конструктора HQL. Но результат запроса пуст, и Hibernate возвращает сообщение, как показано ниже.

 2020-08-14 17:22:45.224  WARN 6668 --- [nio-9090-exec-2] o.hibernate.hql.internal.QuerySplitter   : HHH000183: no persistent classes found for query class: select new com.tt.practices6.map.Status(stat.id, stat.status, stat.application.name, stat.application.production.name, stat.log, stat.requestTime, stat.checked, stat.idUserChecked) from com.tt.practices6.model.ApplicationStatus stat
  

Вот мой XML-файл конфигурации hibernate:

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "https://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
        <property name="hibernate.connection.password">passwd</property>
        <property name="hibernate.connection.url">jdbc:postgresql://localhost:5432/postgres</property>
        <property name="hibernate.connection.username">user</property>
        <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQL9Dialect</property>

        <property name="hibernate.current_session_context_class">thread</property>
        <property name="hibernate.show_sql">true</property>

        <mapping class="com.tt.practices6.model.ApplicationStatus"/>
        <mapping class="com.tt.practices6.model.Application"/>
        <mapping class="com.tt.practices6.model.Production"/>
        <mapping class="com.tt.practices6.map.Status"/>
    </session-factory>
</hibernate-configuration>
  

Метод с запросом:

     @Transactional
    @GetMapping("/applicationsStatus/map/list")
    public ResponseEntity<List<Status>> getAllMappedApplicationsStatus() {

        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
        Session session = sessionFactory.getCurrentSession();
        Transaction tx = session.beginTransaction();

        Query<Status> statusesQuery = session.createQuery(
                "select new com.tt.practices6.map.Status(stat.id, stat.status, "  
                        "stat.application.name, stat.application.production.name, "  
                        "stat.log, stat.requestTime, stat.checked, stat.idUserChecked) "  
                        "from com.tt.practices6.model.ApplicationStatus stat"
        );

        System.out.println(statusesQuery.getResultList());
        List<Status> statuses = new ArrayList<>(statusesQuery.list());

        tx.rollback();
        sessionFactory.close();

        return ResponseEntity.ok().body(statuses);
    }
  

Объект ApplicationStatus:

 @Entity
@Table(name = "applications_status")
public class ApplicationStatus {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private boolean status;

    @ManyToOne(fetch = LAZY)
    @JoinColumn(name="guid_application", referencedColumnName = "guid")
    @JsonBackReference
    private Application application;

    private String log;

    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
    private LocalDateTime requestTime;

    private boolean checked;

    @Column(name = "id_user_checked")
    private Long idUserChecked;

    public ApplicationStatus() {
    }

   // setters and getters
  

Объект состояния:

 public class Status {

    private Long id;

    private boolean status;

    private String applicationName;

    private String productionName;

    private String log;

    private LocalDateTime requestTime;

    private boolean checked;

    private Long idUserChecked;

    public Status(Long id, boolean status, String applicationName, String productionName, String log, LocalDateTime requestTime, boolean checked, Long idUserChecked) {
        this.id = id;
        this.status = status;
        this.applicationName = applicationName;
        this.productionName = productionName;
        this.log = log;
        this.requestTime = requestTime;
        this.checked = checked;
        this.idUserChecked = idUserChecked;
    }

// setters and getters
  

Ответ №1:

Проверьте имя таблицы в аннотации @Table, возможно, все заглавные буквы будут работать. Вероятно, вам также нужно предоставить схему.

Комментарии:

1. Заглавные буквы не помогли.

Ответ №2:

Класс Status не объявлен ни с какой аннотацией @Entity. Но для него определено отображение <mapping class="com.tt.practices6.map.Status"/> . Итак, в режиме гибернации будет ожидаться статус объекта.

Для вашей цели вы можете сначала запросить ApplicationStatus. Затем, после извлечения значений в Query<ApplicationQuery> , вы можете создать пользовательский объект. Или же удалите отображение в xml и попробуйте свой код.

Комментарии:

1. Я удалил Status из XML, и проблема та же. Также я пытаюсь с простым запросом Query<ApplicationStatus> q = session.createQuery("select stat from com.tt.practices6.model.ApplicationStatus stat"); , и проблема все та же…

2. во-первых, почему вы указываете полное имя в запросе для com.tt.practices6.model.ApplicationStatus . используйте просто ApplicationStatus . Во-вторых, когда вы проектируете полный класс, SELECT stat необязательно. Например, String hql = "FROM Employee E WHERE E.id = 10" ; Query query = session.createQuery(hql);

3. ApplicationStatus Только с ошибкой возврата в спящий режим ApplicationStatus is not mapped . Также запрос без SELECT имеет проблему с No persistent classes found for query class . Знаете ли вы какое-либо другое решение для отображения пользовательского объекта непосредственно из базы данных? Я отказываюсь от HQL…