Search code examples
javajpaglassfishclasscastexception

Weird java.lang.ClassCastException thrown


I'm experimenting with JPA and Glassfish 4.0.

I've written a user class like this (just relevant parts and i'm not sure if it compiles):

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;
   }
}

My TestController (just relevant parts):

@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 "";

}

And my Country bean is just a plain bean with simple attibutes located in:

dk.iqtools.entity

In general it works, but if i encounter an error in my code i persistently receive the following error:

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)

the offending statement is this:

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

Can anybody tell my why it happens? If everything runs as expected the user is inserted into the database. But if i for instanse tries to insert a user that already exists i receive a database error.

Next time through i receive the weird exception. I can't understand why a class can't be cast to itself.

I have to restart my GF instance to get rid of it.

Not very production-like.

Thanks for any input.


Solution

  • I have just had to deal with this same type of Exception; "Can't cast X to X." Where "X" is the same class.

    It turned out to be 2 problems feeding into each other. I had made a change in some of my code's pom.xml file (maven's makefile) that said my class was "to be included" (compiled instead of provided) in the WAR file. But it was also available in the "outer" EAR module.

    The class loader was dealing with 2 different instances of the same jar file (i.e., 2 copies of it). This made the class loader think it was 2 different classes, causing the Exception.

    To ultimately fix it I had to change compiled to provided in the WAR file pom.xml, but make sure the EAR file's pom did include the projects jar files.

    But then I also had to take the step to make sure that I had run "clean" to delete all the WAR and EAR file's jar library contents so that there were no extra copies to be found.

    It can get confusing to sort out the contents of the files since the WAR was in the EAR and you had to un-zip the WAR to get a listing of its contents and running the build multiple times made for differing dates on the files.