Nate Uni
Nate Uni

Reputation: 943

Hibernate errors: "java.lang.Integer cannot be cast to java.lang.String" and so on

I have situation where a movie can have lots of reviews, but a review is only ever related to one movie. I have had the issue as stated below, but as I have now tried so many permutations, I am actually little confused, so before I mess with my code anymore I thought it best to ask here.

Q.How should this be set up? Can I just hard set an movie_id as an int, in the review before I save a review? Or do I need to have a MovieDTO movie object as one of the objects in ReviewDTO class? And when I create a review object to be saved, that I call review.setMovie(someMovieObject)?

So here is what was going on in my code with errors:

  1. First it complained that a not-null movie reference was not set (Hibernate : not-null property references a null or transient value), so after not being able to fix it, someone suggested to remove the constraint, to see if it would work.

  2. Now it complains "java.lang.Integer cannot be cast to java.lang.String", but i am confused where there is the type mismatch? Class<->Hibernate or Hibernate<->DB?

Very confused, can someone please shed some light...? Thanks in advance.

package edu.unsw.comp9321.jdbc;

public class ReviewDTO {
    private int id; 
    private String review; 
    private String rating; 
    private int client_id;
    private int movie_id;

    public ReviewDTO() {
    }

    public ReviewDTO(int id, String review, String rating, int client_id, int movie_id) {
        super();
        this.id = id;
        this.review = review;
        this.rating = rating;
        this.client_id = client_id;
        this.movie_id = movie_id;
    }

    public int getid() {
        return id;
    }
    public void setid(int id) {
        this.id = id;
    }

    public String getReview() {
        return review;
    }
    public void setReview(String review) {
        this.review = review;
    }

    public String getRating() {
        return rating;
    }
    public void setRating(String rating) {
        this.rating = rating;
    }

    public int getClient_id() {
        return client_id;
    }
    public void setClient_id(String client_id) {
        this.client_id = new Integer(client_id);
    }   

    public int getMovie_id() {
        return movie_id;
    }
    public void setMovie_id(int movie_id) {
        this.movie_id = movie_id;
    }
}


package edu.unsw.comp9321.jdbc;

import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.OneToMany;


public class MovieDTO implements Comparable {
    private int id;
    private String title;
    private String poster;
    private String director;
    private String actors;
    private String synopsis;
    private String release_date;
    private int cinema_id;
    private Set<GenreDTO> genres = new HashSet<GenreDTO>();
    private Set<ReviewDTO> reviews = new HashSet<ReviewDTO>();
    private double rating;

    public MovieDTO() {
    }

    public MovieDTO(int id, String title, String poster, String director,
            String actors, String synopsis, String release_date, double rating) {
        super();
        this.id = id;
        this.title = title;
        this.poster = poster;
        this.director = director;
        this.actors = actors;
        this.synopsis = synopsis;
        this.release_date = release_date;
        this.rating = rating;
    }

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

    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }

    public String getPoster() {
        return poster;
    }
    public void setPoster(String poster) {
        this.poster = poster;
    }

    public String getDirector() {
        return director;
    }
    public void setDirector(String director) {
        this.director = director;
    }

    public String getActors() {
        return actors;
    }
    public void setActors(String actors) {
        this.actors = actors;
    }

    public String getSynopsis() {
        return synopsis;
    }
    public void setSynopsis(String synopsis) {
        this.synopsis = synopsis;
    }

    public String getRelease_date() {
        return release_date;
    }
    public void setRelease_date(String release_date) {
        this.release_date = release_date;
    }

    public Set<GenreDTO> getGenres() {
        return genres;
    }
    public void setGenres(Set<GenreDTO> genres) {
        this.genres = genres;
    }

    public Set<ReviewDTO> getReviews() {
        return reviews;
    }
    public void setReviews(Set<ReviewDTO> reviews) {
        this.reviews = reviews;
    }

    public int getCinema_id() {
        return cinema_id;
    }
    public void setCinema_id(int cinema_id) {
        this.cinema_id = cinema_id;
    }

    public double getRating() {
        return rating;
    }
    public void setRating(double rating) {
        this.rating = rating;
    }

    @Override
    public int compareTo(Object o) {
        MovieDTO other = (MovieDTO) o;
        if (this.rating > other.rating) return -1;
        if (this.rating < other.rating) return 1;
        return 0;
    }
}

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="edu.unsw.comp9321.jdbc.ReviewDTO" table="Review" >
        <id column="id" name="id">
            <generator class="identity" />
        </id>
        <property column="review" name="review" type="string" />
        <property column="rating" name="rating" type="string" />
        <property column="client_id" name="client_id" type="string" />
        <property column="movie_id" name="movie_id" type="string" />
    </class>
</hibernate-mapping>

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="edu.unsw.comp9321.jdbc.MovieDTO" table="Movie" >
        <id column="id" name="id">
            <generator class="identity" />
        </id>
        <property column="title" name="title" type="string" />
        <property column="poster" name="poster" type="string" />
        <property column="director" name="director" type="string" />
        <property column="actors" name="actors" type="string" />
        <property column="synopsis" name="synopsis" type="string" />
        <property column="release_date" name="release_date" type="string" />
        <set name="genres" table="MovieHasGenre" >
            <key column="movie_id" not-null="true" />
            <many-to-many class="edu.unsw.comp9321.jdbc.GenreDTO" column="genre_id" />
        </set>
        <set name="reviews" table="Review" >
            <key column="movie_id" />
            <one-to-many class="edu.unsw.comp9321.jdbc.ReviewDTO" />
        </set>
    </class>
</hibernate-mapping>

Upvotes: 0

Views: 2451

Answers (1)

j.con
j.con

Reputation: 889

The first error you receive is because you define <key column="movie_id" not-null="true" /> which means movie_id can not be null inside the GenreDTO of that MovieDTO. Somewhere in your code that value is null when trying to persist (not enough code shown to tell you where.)

The second error is because you define <property column="movie_id" name="movie_id" type="string" /> but in your ReviewDTO movie_id is an int. They should be the same.

As for your question, whether you should use movie_id or a MovieDTO in your ReviewDTO. That depends on a few things. Bi-directional relationships are fine (meaning ReviewDTO has a MovieDTO attached to it while that same MovieDTO has that same ReviewDTO in it's list of Reviews. However scale-ability and performance issues will happen if you have millions of entities. On the contrary leaving just movie_id Integer means anytime you want the MovieDTO object from a ReviewDTO you will have another database call... however this may not be too costly because if it was bi-directional, that call would have happened regardless.

Upvotes: 2

Related Questions