2012-10-27 30 views
0

我目前正在改進一個工作正常的舊項目,我不必修改代碼和數據庫,我所能做的就是爲它構建正確的映射...Java JPA類關聯,NullPointerException?

有演員,角色和電影類......與數據庫中的相應的3個表:

表 '演員':

`id` INT 
`name` VARCHAR 

表 '角色':

`film` INT 
`actor` INT 
`role` VARCHAR 
PRIMARY KEY (film, actor, role) 
FOREIGN KEY (film) REFERENCES film(id) 

表「電影」:

`id` INT 
`title` VARCHAR 

因此有兩個協會提出,[ONE演員在一部電影一個角色]和[ONE影片包含有關其respectives演員很多角色。

基本上,應該有電影類中的方法,它允許創建關聯到一個演員

film.createRole(actor, "Role"); //returning a role 

我越來越所有的時間同樣的錯誤一個新的角色:從休眠的Java NullPointerException異常。我想我的代碼有一個誤解,任何想法我怎麼能做正確的映射?

代碼:

Movie.java:

@Entity 
@Table(name = "movie") 
public class Movie implements Serializable 
{ 
@Id 
@GeneratedValue 
private int id; 
private String title; 

@OneToMany 
@JoinTable(name = "role", 
joinColumns = { 
@JoinColumn(name="role") 
} 
) 
private List<Role> roles; 

//Getters and setters 

public Role createRole(Actor actor, String role) 
{ 
Role myRole = new Role(); 
RoleId roleId = new RoleId(); 
roleId.setMovie(this.id); 
roleId.setRole(role); 
roleId.setActor(actor.getId()); 
myRole.setId(roleId); 
return myRole; 
} 
} 

Role.java:

@Entity 
@Table(name = "role") 
public class Role implements Serializable 
{ 
@EmbeddedId 
private RoleId roleId; 

//Getters and setters 
} 

RoleId.java:

@Embeddable 
public class RoleId implements Serializable 
{ 

@ManyToOne(optional=true) 
@JoinTable(name = "role", joinColumns = { 
@JoinColumn(name="movie")}) 
private int movie; 

@ManyToOne(optional=true) 
@JoinTable(name = "role", joinColumns = { 
@JoinColumn(name="actor") 
}) 
private int actor; 

private String role; 

//Getters and setters 
} 

Actor.java:

@Entity 
@Table(name = "actor") 
public class Actor implements Serializable 
{ 
@Id 
@GeneratedValue 
private int id; 
private String name; 


@OneToMany 
@JoinTable(name = "role", joinColumns = { 
@JoinColumn(name="role", unique = true) }) 
private List<Role> roles; 

//Getters and setters 

} 

那麼錯誤呢? 謝謝。

+2

輸出哪來的堆棧跟蹤? –

+0

您可能希望更好地格式化您的問題以使其可讀! – Vikdor

+2

真的需要看一個堆棧跟蹤來幫助你進一步。 – JamesB

回答

1

我認爲你有不好的註解映射。看看我是如何做到的。

角色ID

import java.io.Serializable; 

import javax.persistence.Embeddable; 
import javax.persistence.JoinColumn; 
import javax.persistence.ManyToOne; 

@Embeddable 
public class RoleId implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @ManyToOne(optional = false) 
    @JoinColumn(name = "movie") 
    private Movie movie; 

    @ManyToOne(optional = false) 
    @JoinColumn(name = "actor") 
    private Actor actor; 

    private String role; 

    public Movie getMovie() { 
     return movie; 
    } 

    public void setMovie(Movie movie) { 
     this.movie = movie; 
    } 

    public Actor getActor() { 
     return actor; 
    } 

    public void setActor(Actor actor) { 
     this.actor = actor; 
    } 

    public String getRole() { 
     return role; 
    } 

    public void setRole(String role) { 
     this.role = role; 
    } 

    @Override 
    public String toString() { 
     return "movie=" + movie.getTitle() + ", actor=" + actor.getName() 
       + ", role=" + role; 
    } 
} 

角色

@Entity 
@Table(name = "role") 
public class Role implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @EmbeddedId 
    private RoleId id; 

    public RoleId getId() { 
     return id; 
    } 

    public void setId(RoleId id) { 
     this.id = id; 
    } 

    @Override 
    public String toString() { 
     return getId().toString(); 
    } 
} 

演員

@Entity 
@Table(name = "actor") 
public class Actor implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue 
    @Column(name = "id") 
    private int id; 
    private String name; 

    @OneToMany 
    @JoinColumn(name = "actor") 
    private List<Role> roles; 

    public int getId() { 
     return id; 
    } 

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

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public List<Role> getRoles() { 
     return roles; 
    } 

    public void setRoles(List<Role> roles) { 
     this.roles = roles; 
    } 

    @Override 
    public String toString() { 
     StringBuilder builder = new StringBuilder(124); 
     builder.append(name).append(" roles "); 
     builder.append(Arrays.toString(roles.toArray())); 
     return builder.toString(); 
    } 
} 

電影

@Entity 
@Table(name = "movie") 
public class Movie implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue 
    @Column(name = "id") 
    private int id; 

    private String title; 

    @OneToMany 
    @JoinColumn(name = "movie") 
    private List<Role> roles; 

    public Role createRole(Actor actor, String role) { 
     Role myRole = new Role(); 
     RoleId roleId = new RoleId(); 
     roleId.setMovie(this); 
     roleId.setRole(role); 
     roleId.setActor(actor); 
     myRole.setId(roleId); 
     return myRole; 
    } 

    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 List<Role> getRoles() { 
     return roles; 
    } 

    public void setRoles(List<Role> roles) { 
     this.roles = roles; 
    } 

    @Override 
    public String toString() { 
     StringBuilder builder = new StringBuilder(124); 
     builder.append(title).append(" roles "); 
     builder.append(Arrays.toString(roles.toArray())); 
     return builder.toString(); 
    } 
} 

個MySQL表

CREATE TABLE `actor` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB; 

CREATE TABLE `movie` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT, 
    `title` varchar(255) DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB; 

CREATE TABLE `role` (
    `movie` bigint(20) NOT NULL, 
    `actor` bigint(20) NOT NULL, 
    `role` varchar(255) NOT NULL DEFAULT '', 
    PRIMARY KEY (`movie`,`actor`,`role`), 
    CONSTRAINT `role_movie_movie` FOREIGN KEY (`movie`) REFERENCES `movie` (`id`), 
    CONSTRAINT `role_actor_actor` FOREIGN KEY (`actor`) REFERENCES `actor` (`id`) 
) ENGINE=InnoDB; 
INSERT INTO actor(name) VALUES('Arnold Schwarzenegger'); 
INSERT INTO actor(name) VALUES('Michael Biehn'); 
INSERT INTO actor(name) VALUES('Linda Hamilton'); 

INSERT INTO movie(title) VALUES('Termiantor'); 

INSERT INTO role VALUES(1, 1, 'Terminator'); 
INSERT INTO role VALUES(1, 2, 'Kyle Reese'); 
INSERT INTO role VALUES(1, 3, 'Sara Connor'); 

下面的源代碼執行後:

public static void main(String[] args) { 
    movieTest(); 
} 

public static void movieTest() { 
    Session session = HibernateUtil.getSessionFactory().openSession(); 
    showEntities(session, Movie.class, "Movies"); 
    showEntities(session, Actor.class, "Actors"); 
    showEntities(session, Role.class, "Roles"); 
} 

private static void showEntities(Session session, Class<?> entity, 
     String name) { 
    System.out.println(name); 
    for (Object item : session.createCriteria(entity).list()) { 
     System.out.println(item); 
    } 
} 

你會看到這樣的

Movies 
Termiantor roles [movie=Termiantor, actor=Arnold Schwarzenegger, role=Terminator, movie=Termiantor, actor=Michael Biehn, role=Kyle Reese, movie=Termiantor, actor=Linda Hamilton, role=Sara Connor] 
Actors 
Arnold Schwarzenegger roles [movie=Termiantor, actor=Arnold Schwarzenegger, role=Terminator] 
Michael Biehn roles [movie=Termiantor, actor=Michael Biehn, role=Kyle Reese] 
Linda Hamilton roles [movie=Termiantor, actor=Linda Hamilton, role=Sara Connor] 
Roles 
movie=Termiantor, actor=Arnold Schwarzenegger, role=Terminator 
movie=Termiantor, actor=Michael Biehn, role=Kyle Reese 
movie=Termiantor, actor=Linda Hamilton, role=Sara Connor