2013-11-08 1 views
4

Я экспериментирую с JPA и Glassfish 4.0.Weird java.lang.ClassCastException throw

Я написал класс пользователей, как это (только соответствующие части, и я не уверен, если он компилирует):

public class User implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Basic(optional = false) 
    @Column(name = "id") 
    private Integer id; 
    @Basic(optional = false) 
    @NotNull 
    @Size(min = 1, max = 50) 
    @Column(name = "first_name") 
    private String firstName; 

    @JoinColumn(name = "country_id", referencedColumnName = "id") 
    @ManyToOne(optional = false) 
    private Country country; 

    public void setCountry(Country countryId) { 
     this.country = countryId; 
    } 
} 

Мой TestController (только соответствующие части):

@ManagedBean(name = "testController", eager = true) 
@RequestScoped 
public class TestController implements Serializable { 
    @EJB 
    private dk.iqtools.session.UserFacade userFacade; 

    public String Insert(){ 
     factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); 
     EntityManager em = factory.createEntityManager(); 
     Query cq = em.createQuery("select c from Country c where c.id = 302"); 
     List<Country> countryList = cq.getResultList(); 

    User user = new User(); 
    user.setFirstName("Hans123"); 
    user.setLastName("Knudsen333"); 
    user.setCountry((Country)countryList.get(0)); <- throws an ERROR 
    user.setPassword("secret"); 
    user.setYearOfBirth(1966); 
    user.setGender(1); 
    user.setEmail("[email protected]"); 

    userFacade.create(user); 

return ""; 

}

И моя страна боб просто обычный боб с простыми, расположенными в атрибутах объявления:

dk.iqtools.entity

В целом это работает, но если возникает ошибка в моем коде я постоянно появляется следующее сообщение об ошибке:

Caused by: java.lang.ClassCastException: 
dk.iqtools.entity.Country cannot be cast to dk.iqtools.entity.Country 
at dk.iqtools.controller.TestController.Insert(TestController.java:65) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 

заявление нарушившая это:

user.setCountry((Country)countryList.get(0)); 

Может кто-нибудь сказать мне, почему это происходит? Если все работает так, как ожидается, пользователь будет вставлен в базу данных. Но если i для instanse пытается вставить пользователя, который уже существует, я получаю ошибку базы данных.

В следующий раз я получаю странное исключение. Я не могу понять, почему класс нельзя использовать для себя.

Мне нужно перезагрузить свой экземпляр GF, чтобы избавиться от него.

Не очень продуктоподобный.

Спасибо за любой ввод.

+1

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

+0

Возможно, это так. но как это происходит? –

+0

Является ли это частью одного EAR? Вы на 100% не можете столкнуться с загрузчиками классов? Например. два EAR или WAR, каждый из которых имеет свой собственный модельный класс («Страна») и вызывает друг друга или что-то вроде этого? –

ответ

0

Мне просто пришлось иметь дело с тем же типом исключения; «Нельзя отбрасывать X в X». Где «X» - тот же класс.

Оказалось, что 2 проблемы связаны друг с другом. Я внес изменения в некоторый файл pom.xml моего кода (makefile maven), в котором говорится, что мой класс был «включен» (скомпилирован вместо предоставленного) в WAR-файл. Но он также был доступен в «внешнем» модуле EAR.

Погрузчик классов имел дело с 2 различными экземплярами одного и того же файла jar (то есть, 2 его копии). Это заставило загрузчика классов думать, что это 2 разных класса, вызывая исключение.

Чтобы в конечном итоге исправить это, мне пришлось скомпилировать его в файл WAR pom.xml, но убедитесь, что pom файла EAR содержит файлы jar проектов.

Но тогда я также должен был сделать шаг, чтобы убедиться, что я запустил «чистый», чтобы удалить содержимое библиотеки библиотеки баннеров WAR и EAR, чтобы не было обнаружено никаких дополнительных копий.

Может возникнуть путаница в сортировке содержимого файлов, так как WAR была в EAR, и вам нужно было разблокировать WAR, чтобы получить список его содержимого и запустить сборку несколько раз для разных дат на файлы.

1

Это происходит из-за того, что некоторые из оставшихся от EntityManagerFactory из старой версии вашего приложения каким-то образом его загрузчики классов выжили после перераспределения вашего приложения.

Что нужно сделать, так это закрыть EntityManagerFactory перед перераспределением, вы можете использовать ServletContextListeners для достижения этого, они позволяют присоединять события к вашей инициализации и уничтожению веб-приложений.

Вот очень простой пример реализации контекста сервлета: http://4dev.tech/2015/08/example-of-servletcontextlistener-implementation/

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

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