2016-06-22 12 views
2

У меня возникла странная проблема в моем приложении, которая работает в Spring Boot 1.4.0M3, которая использует реализацию Spring cache, где поставщик Redis, где я получаю classCastException, что тот же объект не может быть литымjava.lang.ClassCastException: DTOObject не может быть передан DTOObject

Я использую MongoDB в качестве базы данных и у меня есть пользовательский объект, который содержит список ролей объекта загружается лениво и роли внутри содержит разрешение объект, как показано ниже

@Document 
@Data 
public class User implements Serializable{ 
private String passwordResetToken; 

private boolean enabled = false; 

@DBRef(lazy= true) 
private List<Role> roleList; 
} 

Моей роль DTO как ниже

@Data 
@Document 
public class Role implements Serializable{ 
    private String roleName; 
    private String description; 
    @DBRef(lazy= true) 
    private List<Permission> permissions; 
} 

Теперь, когда моя весна MVC загружает все роли, я вызываю все разрешения, и поскольку это повторяющаяся операция, я думал о кэшировании результата и использовании redis и при загрузке значения ролей, которое я получаю ниже исключения.

raised java.lang.ClassCastException: com.learning.securedapp.domain.Permission cannot be cast to com.learning.securedapp.domain.Permission 

Помогите преодолеть эту ошибку.

Я прилагаю source code в мой проект и я получаю ошибку в строке 91 RoleController.java

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

+1

Если класс загружается дважды разными загрузчиками классов, jvm считает их неравными. Наверное, это то, что с тобой происходит. – joshiste

+0

Похоже, вы используете военный файл, поэтому проблема, вероятно, связана с нашим контейнером приложения, содержащим несколько версий одного и того же класса. – Magnus

+0

Я бегу от ide, и вижу только одну версию класса разрешений. – rajadilipkolli

ответ

3

Когда вы используете DevTools с кешированием, вам необходимо знать this limitation.

Когда объект сериализуется в кеш, загрузчик класса приложения является C1. Затем, после изменения кода/конфигурации, devtools автоматически перезапускает контекст и создает новый загрузчик классов (C2). Когда вы нажимаете этот метод кеша, абстракция кеша находит запись в кеше и десериализует ее из хранилища. Если в библиотеке кэша не учитывается загрузчик классов контекста, к этому объекту будет прикреплен неверный загрузчик классов (что объясняет это странное исключение A cannot be cast to A).

TL;DR не сериализуйте классы с помощью devtools, если библиотека кеша не использует загрузчик классов. Или поместить вашу библиотеку кэша in the application classloader:

restart.include.yourcache=/my-cache-lib-[\\w-]+\.jar 
+0

благодарит @nicoll, не могли бы вы предоставить мне пример того, как исключить библиотеку кеша в загрузчик классов приложений. – rajadilipkolli

+0

Вторая ссылка имеет пример. Фактически вы должны включить _ cache library в загрузчик класса приложения. Я обновлю проблему. –

+0

Я следил за предоставленной вами ссылкой и добавил свойство restart.exclude.cache = jedis * .jar в META-INF/spring-devtools.properties, но я по-прежнему сталкиваюсь с той же проблемой. Я добавил jedis, потому что я использую redis в качестве поставщика кеша – rajadilipkolli

1

Я фактически попробовал предложенное решение (и многие его вариации) не повезло. Например, это не остановило проблему возникновения:

restart.include.cache=/spring-data-redis-.*.jar 

Я обновил выше выноска конкретную версию я использовал и до сих пор не работает.

Что я в итоге сделал, что делало работу, чтобы исключить spring-boot-devtools из моего проекта. Я использую Maven, поэтому аннотация была такой:

<dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-devtools</artifactId> 
     <version>[1.5.9,)</version> 
     <scope>provided</scope> 
    </dependency> 

Это предотвратит загрузку любой версии, равной или превышающей 1,5,9. После того, как я включил вышеизложенное, все работало, как ожидалось. Я знаю, что это не идеальное решение для всех, но я мало использовал функции перезапуска devtools, поэтому для меня это был хороший подход.

 Смежные вопросы

  • Нет связанных вопросов^_^