java - 如果我在 Spring 中运行 Hibernate 请求,为什么会收到 ClassCastException?

标签 java spring hibernate classcastexception

运行 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)
    ...

运行单元测试时我无法重新创建此异常。

这些是我的类(class): 权限:

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() + "'" + "}";
    }

}

数据操作符:

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.misc.Launcher$AppCLassLoader 和 org.springframework.boot.devtools.restart.classloader.RestartClassLoader。

对此我能做什么?

最佳答案

正如 Ed Schaller 在另一个回复中提到的,问题来自于类是从两个不同的实体加载的。

尽管如此,我没有更改类路径,而是找到了一种方法来解决此问题:使用 BootstrapServiceRegistry 并添加应用程序和 hibernate 的类加载器。

public class HibernateUtil {
    private static SessionFactory sessionFactory;
    static {
        final StandardServiceRegistry registry = new StandardServiceRegistryBuilder(
                createHibernateBootstrapServiceRegistry()).configure().build();
        try {
            sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
        } catch (Exception e) {
            StandardServiceRegistryBuilder.destroy(registry);
        }
    }

    private static BootstrapServiceRegistry createHibernateBootstrapServiceRegistry() {
        ClassLoader tccl = Thread.currentThread().getContextClassLoader();
        ClassLoader hibernateCl = BootstrapServiceRegistry.class.getClassLoader();
        return new BootstrapServiceRegistryBuilder().applyClassLoader(tccl).applyClassLoader(hibernateCl).build();
    }

    public static Session openSession() {
        return sessionFactory.openSession();
    }
}

关于java - 如果我在 Spring 中运行 Hibernate 请求,为什么会收到 ClassCastException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60821565/

相关文章:

spring - 当 spring.profiles.active 设置多个 Spring 的环境配置文件时,优先顺序是什么

hibernate - 非严格读/写与 hibernate 中的读/写?

java - 使用 java servlet 将数据从一个 html 页面传递到另一页面

java - 当注册多个 ClientHttpRequestInterceptor 时,RestTemplate 的行为是什么?

java - JsonPath - 使用一个 DocumentContext 如何使用默认配置和 Option.AS_PATH_LIST 进行查询?

java - x 天后使用 Spring 运行一次任务

java.sql.SQLIntegrityConstraintViolationException : Duplicate entry '0' for key 'PRIMARY'

java - JPA 标准查询 : writing query with array operators

java - 设置CheckboxTableViewer的标题

java - 错误: Client does not support authentication protocol requested by server; consider upgrading MySQL client