Hibernate @ManyToOne @JoinColumn 始终为空

Posted

技术标签:

【中文标题】Hibernate @ManyToOne @JoinColumn 始终为空【英文标题】:Hibernate @ManyToOne @JoinColumn is always null 【发布时间】:2014-11-11 22:53:41 【问题描述】:

我正在尝试使用休眠实现两个表之间的一对多关系。这是我的代码:

@Entity
public class Board

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

@Column
private String owner;

@Column
private String title;

@Column
private String refresh;

@Column
private Timestamp  createDate;

@Column
private Timestamp modifyDate;

@OneToMany(mappedBy="board", cascade=CascadeType.ALL)
private List<Item> items;

public long getId()

    return id;

public void setId(long id)

    this.id = id;


public String getOwner()

    return owner;

public void setOwner(String owner)

    this.owner = owner;


public String getTitle()

    return title;

public void setTitle(String title)

    this.title = title;


public String getRefresh()

    return refresh;

public void setRefresh(String refresh)

    this.refresh = refresh;


public Timestamp getCreateDate()

    return createDate;

public void setCreateDate(Timestamp createDate)

    this.createDate = createDate;


public Timestamp getModifyDate()

    return modifyDate;

public void setModifyDate(Timestamp modifyDate)

    this.modifyDate = modifyDate;


public List<Item> getItems()

    return items;

public void setItems(List<Item> items)

    this.items = items;


第二张桌子:

@Entity
public class Item

public enum Type
  
     link,
     image, 
     presentation;  


public enum javascript
  
     enable,
     disable;  
  

@Id
@Column
@GeneratedValue
private long id;

@ManyToOne(fetch = FetchType.EAGER)  
@JoinColumn(name = "board_id")  
private Board board; 

@Column
private Type type;

@Column(length = 10000)
private String link;

@Column
private String image;

@Column
private String presentation;

@Column
private String time;

@Column
private JavaScript javaScript;

@Column
private String first;

@Column
private String last;

@Transient
private MultipartFile imageFile;

@Transient
private MultipartFile presentationFile;

public long getId()

    return id;

public void setId(long id)

    this.id = id;


public Board getBoard()

    return board;

public void setBoard(Board board)

    this.board = board;


public Type getType()

    return type;

public void setType(Type type)

    this.type = type;


public String getLink()

    return link;

public void setLink(String link)

    this.link = link;


public String getImage()

    return image;

public void setImage(String image)

    this.image = image;

public String getPresentation()

    return presentation;

public void setPresentation(String presentation) 

    this.presentation = presentation;


public String getTime()

    return time;

public void setTime(String time)

    this.time = time;


public JavaScript getJavaScript()

    return javaScript;

public void setJavaScript(JavaScript javaScript)

    this.javaScript = javaScript;


public String getFirst()

    return first;

public void setFirst(String first)

    this.first = first;


public String getLast() 

    return last;

public void setLast(String last)

    this.last = last;


public MultipartFile getImageFile()

    return imageFile;

public void setImageFile(MultipartFile imageFile)

    this.imageFile = imageFile;


public MultipartFile getPresentationFile()

    return presentationFile;

public void setPresentationFile(MultipartFile presentationFile) 

    this.presentationFile = presentationFile;


但我无法让它工作。 board_id 在项目表中始终为空。 Hibernate 输出看起来很奇怪:

Hibernate: insert into Board (board_id, createDate, modifyDate, owner, refresh, title) values (null, ?, ?, ?, ?, ?)
Hibernate: insert into Item (id, board_id, first, image, javaScript, last, link, presentation, time, type) values (null, ?, ?, ?, ?, ?, ?, ?, ?, ?)

有什么想法吗?

【问题讨论】:

您必须在持久化项目时提供代码。还要记住,尽管有双向映射和级联,但您必须在两侧设置关系 休眠输出正确。那些nulls 是主 ID,Hibernate 让数据库自动设置 ID 如何设置两边的关系?当我检查项目表时,“board_id”列始终为空。 这个问题你解决了吗? 【参考方案1】:

要扩展@Antoniossss 的评论,您需要在持久化之前设置双方的关系。

// Create owning entity first
Board board = new Board();
// Create child entities
Item item1 = new Item();
item1.setBoard(board); // set relation on Item side
board.getItems().add(item1); // set relation on Board side

另请注意,立即初始化集合字段被认为是一种好习惯,这样Board#getItems() 永远不会返回null

【讨论】:

【参考方案2】:

快速提示: 将@GeneratedValue 用于@Id 字段时,最好避免在该字段上显式设置值。

@GeneratedValue 表示 Hibernate 或您选择的数据库将设置实体的 id(取决于您的 GenerationType),因此设置显式值或允许公开设置可能会导致抛出特定于休眠的StaleStateException

所以你不应该在你的构造函数中包含 id 并删除:

public void setId(long id)

    this.id = id;

【讨论】:

以上是关于Hibernate @ManyToOne @JoinColumn 始终为空的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate @ManyToOne 调用自己

Hibernate @ManyToOne引用了一个未知实体

org.hibernate.PersistentObjectException:分离的实体传递给坚持@ManyToOne

为啥在这个 Hibernate 映射中使用 @ManyToOne 而不是 @OneToOne?

Hibernate:具有两个不同的 ManyToOne 关系的子表

Hibernate CriteriaQuery where - ManyToOne 字段