我目前正在改进一个工作正常的旧项目,我不必修改代码也不需要修改数据库,我所能做的就是为它构建正确的映射...
有Actor,Role和Movie类......数据库中有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
所以有两个关联,[一个演员在一部电影中扮演一个角色],[一部电影包含与各自演员相关联的多个角色]。
基本上,Movie类中应该有一个方法允许创建一个与actor相关联的新角色
film.createRole(actor, "Role"); //returning a role
我总是得到同样的错误:来自Hibernate的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
}
那么错误在哪里? 感谢。
答案 0 :(得分: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