Почему я получаю ClassCastException, если я запускаю запрос Hibernate весной? - PullRequest
0 голосов
/ 24 марта 2020

Во время работы приложения Spring я получил следующее исключение:

java.lang.ClassCastException: project.db.dbmodels.Permission cannot be cast to project.db.dbmodels.Permission
    at project.db.DataOperator.setUpDefaultPermission(DataOperator.java:573)
    at project.web.WebController.start(WebController.java:18)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879)
    ...

Я не могу воссоздать это исключение при выполнении юнит-тестов.

Это мои занятия: Разрешение:

package project.db.dbmodels;

import java.util.*;
import javax.persistence.*;

@Entity
@Table(name = "permission")
public class Permission {

    @Id
    @GeneratedValue
    @Column(name = "id")
    private int id;

    @Column(name = "name")
    private String name;

    @OneToMany(mappedBy = "permission", cascade = CascadeType.ALL)
    private Set<Permission_PermissionRole> permissionPermissionRole = new HashSet<Permission_PermissionRole>();

    public Permission() {
    }

    public Permission(int id, String name, Set<Permission_PermissionRole> permissionPermissionRole) {
        this.id = id;
        this.name = name;
        this.permissionPermissionRole = permissionPermissionRole;
    }

    public int getId() {
        return this.id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<Permission_PermissionRole> getPermissionPermissionRole() {
        return this.permissionPermissionRole;
    }

    public void setPermissionPermissionRole(Set<Permission_PermissionRole> permissionPermissionRole) {
        this.permissionPermissionRole = permissionPermissionRole;
    }

    public void addPermissionPermissionRole(Permission_PermissionRole permissionPermissionRole) {
        this.permissionPermissionRole.add(permissionPermissionRole);
    }

    public Permission id(int id) {
        this.id = id;
        return this;
    }

    public Permission name(String name) {
        this.name = name;
        return this;
    }

    public Permission permissionPermissionRole(Set<Permission_PermissionRole> permissionPermissionRole) {
        this.permissionPermissionRole = permissionPermissionRole;
        return this;
    }

    @Override
    public boolean equals(Object o) {
        if (o == this)
            return true;
        if (!(o instanceof Permission)) {
            return false;
        }
        Permission permission = (Permission) o;
        return id == permission.id && Objects.equals(name, permission.name)
                && Objects.equals(permissionPermissionRole, permission.permissionPermissionRole);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }

    @Override
    public String toString() {
        return "{" + " id='" + getId() + "'" + ", name='" + getName() + "'" + "}";
    }

}

DataOperator:

package project.db;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.PersistenceException;
import javax.persistence.RollbackException;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;

import project.db.dbmodels.*;
import org.apache.log4j.Logger;

public class DataOperator {
    final static Logger log = Logger.getLogger(DataOperator.class);


    private static boolean setUpDefaultPermission(boolean change) {
        SessionFactory sf = HibernateUtil.getSessionFactory();
        if (sf == null) {
            return false;
        }
        Session session = sf.openSession();
        session.beginTransaction();
        boolean arePermissionsReady = true;
        // Setup permission "AcessAdminarea"
        String request = "FROM Permission WHERE name = 'Acess Adminarea'";
        Query<Permission> query = session.createQuery(request, Permission.class);
        query.setMaxResults(1);
        Permission permAdminArea = null;
        try {
            permAdminArea = query.uniqueResult();//The Exception occures here
        } catch (PersistenceException e) {
            return false;
        }
        if (permAdminArea == null) {
            arePermissionsReady = false;
            if (change) {
                permAdminArea = new Permission();
                permAdminArea.setName("Acess Adminarea");
                session.save(permAdminArea);
            }
        }
        // Setup permissionrole "Admin"
        request = "FROM PermissionRole WHERE name = 'Admin'";
        Query<PermissionRole> query2 = session.createQuery(request, PermissionRole.class);
        PermissionRole roleAdmin = null;
        try {
            roleAdmin = query2.uniqueResult();
        } catch (PersistenceException e) {
            return false;
        }
        if (roleAdmin == null) {
            arePermissionsReady = false;
            if (change) {
                roleAdmin = new PermissionRole();
                roleAdmin.setName("Admin");
                session.save(roleAdmin);
                Permission_PermissionRole permPermrole = new Permission_PermissionRole();
                permPermrole.setPermission(permAdminArea);
                permPermrole.setRole(roleAdmin);
                session.save(permPermrole);
            }
        }
        // Setup permissionrole "Employee"
        request = "FROM PermissionRole WHERE name = 'Employee'";
        query2 = session.createQuery(request, PermissionRole.class);
        PermissionRole roleEmployee = null;
        try {
            roleEmployee = query2.uniqueResult();
        } catch (PersistenceException e) {
            return false;
        }
        if (roleEmployee == null) {
            arePermissionsReady = false;
            if (change) {
                roleEmployee = new PermissionRole();
                roleEmployee.setName("Employee");
                session.save(roleEmployee);
            }
        }

        if (change && !arePermissionsReady) {
            try {
                session.getTransaction().commit();
                arePermissionsReady = true;
            } catch (IllegalStateException e) {
                log.error(String.format("Unable to commit the transaction : %s", e.getMessage()));
            } catch (RollbackException e) {
                log.error(String.format("Unable to commit the transaction : %s", e.getMessage()));
            }
            session.close();
        }
        return arePermissionsReady;
    }


}

При поиске ошибки я попытался получить еще какой-нибудь отладочный контент, поэтому я заменил строку, где произошло исключение, и вставил следующее код в DataOperator:

Object result = query.uniqueResult();
String resultType = result.getClass().toString();
boolean test = result instanceof Permission;
boolean test2 = Permission.class.toString().equals(resultType);

Я установил остановку после этого сегмента и при отладке во время его запуска с помощью Spring я получил:

result: Permission@47 "{ id='15', name='Acess AdminArea'}"
resultType: "class project.db.dbmodels.Permission"
test: false
test2: true

Во время выполнения модульного теста я получил:

result: Permission@47 "{ id='15', name='Acess AdminArea'}"
resultType: "class project.db.dbmodels.Permission"
test: true
test2: true

Редактировать: у них разные загрузчики классов. sun.mis c .Launcher $ AppCLassLoader и org.springframework.boot.devtools.restart.classloader.RestartClassLoader.

Что я могу сделать с этим?

1 Ответ

0 голосов
/ 24 марта 2020

Это происходит, когда рассматриваемый класс загружается из двух (или более) загрузчиков классов. Класс в java уникален только в сочетании с его загрузчиком классов. Вероятно, ваш класс Permission загружается из одного загрузчика классов, а затем он приводится к тому же классу, но загружается из другого загрузчика классов.

Добавьте загрузчик классов в журналы отладки, и вы, скорее всего, увидите проблема и, надеюсь, в какие загрузчики классов загружается класс.

...