Reputation: 943
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:
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.
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
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