![](/img/trans.png)
[英]in OneTOMany mapping foreign key is inserted as null in Hibernate-MySQL
[英]Null values are inserted in the foreign key fields with Hibernate
我有一個Question
實體和Tag
實體,包含getter,setter方法和從question
到tag
的OneToMany
關系以及從question
到user
的OneToOne
關系
public class Question {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@Column(name="title")
private String title;
@Column(name="body")
private String body;
@Temporal(TemporalType.DATE)
@Column(name="date_created")
private Date date_created;
@OneToOne(cascade=CascadeType.ALL)
@JoinColumn(name="user_id")
private User user;
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="tag_id")
private Tag tag;
@Column(name="answer_count")
private int answer_count;
@Column(name="view_count")
private int view_count;
public Question() {
}
標記實體
public class Tag {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@Column(name="name")
private String name;
@Column(name="username")
private String username;
@Temporal(TemporalType.DATE)
@Column(name="date_created")
private Date date_created;
public Tag() {
}
當我嘗試使用Postman插入問題並提供以下詳細信息時:
{
"title": "stefanyyyxx",
"body": "stefandoyee44",
"date_created": "2019-02-27",
"user_id" : 1,
"tag_id": 1,
"answer_count": 0,
"view_count": 0
}
QuestionRepository.java:
@Override
public void save(Question theQuestion) {
// get the current hibernate session
Session currentSession = entityManager.unwrap(Session.class);
// save employee
currentSession.saveOrUpdate(theQuestion);
}
雖然我使用了JoinColumn()
但是為user_id
和tag_id
插入了空值。
MySQL的:
正如@Karol Dowbecki建議的那樣,
將JSON轉換為DTO對象並使用該DTO從其各自的存儲庫中獲取User
, Tag
實體。
最后創建Question實體對象並存儲它。
問題實體
@Entity
@Table(name = "question")
public class Question {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "title")
private String title;
@Column(name = "body")
private String body;
@Temporal(TemporalType.DATE)
@Column(name = "date_created")
private Date dateCreated;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "user_id")
private User user;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "tag_id")
private Set<Tag> tag;
@Column(name = "answer_count")
private int answerCount;
@Column(name = "view_count")
private int viewCount;
}
用戶實體
@Entity
@Table(name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
標記實體
@Entity
@Table(name = "tag")
public class Tag {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "username")
private String username;
@Temporal(TemporalType.DATE)
@Column(name = "date_created")
private Date dateCreated;
}
DTO課程
public class QuestionDTO {
private Long id;
private String title;
private String body;
private Date dateCreated;
private Long user;
private Long tag;
private int answerCount;
private int viewCount;
}
測試類
@Service
public class TestService {
@Autowired
private QuestionRepository questionRepository;
@Autowired
private UserRepository userRepository;
@Autowired
private TagRepository tagRepository;
public void addQuestion(QuestionDTO dto) {
Tag tag = null;
User user = null;
Question question = null;
Set<Tag> tags = null;
tag = tagRepository.findById(dto.getTag());
tags = new HashSet<>();
tags.add(tag);
user = userRepository.findById(dto.getUser());
question = new Question();
question.setTag(tags);
question.setUser(user);
question.setId(dto.getId());
question.setBody(dto.getBody());
question.setTitle(dto.getTitle());
question.setViewCount(dto.getViewCount());
question.setAnswerCount(dto.getAnswerCount());
question.setDateCreated(dto.getDateCreated());
questionRepository.save(question);
}
}
注意 : Question
和Tag
之間的關系是在OneToMany
您必須使用Collection
類型。
您在JSON和@Entity
結構之間存在不匹配。 JSON包含數字標識符,而@Entity
包含表示關系的實際對象。 您最有可能應該引入一個單獨的DTO類來映射此JSON,而在@Repository
您應該根據其ID加載User
和Tag
對象或創建新對象。 你已經有CascadeType.ALL
所以Hibernate會級聯持久化操作。
通常,控制器層應該與存儲庫層分開,除非您正在做非常非常簡單的事情。 這有助於在不更改API合同的情況下改進服務,例如添加新列以進行審計更改。 通過將@Entity
暴露為DTO,您將使您的生活更加艱難。
您應該在子實體外鍵列中添加referencedColumnName
referencedColumnName="your primaray key column name"
編輯:
referencedColumnName
資產是父實體,AssetDetails是子實體在這里我采取了OneToOne關系
Asset.java
@Entity
@Table(name="asset")
public class Asset {
@Id
@GeneratedValue
@Column(name="assetid")
private BigInteger assetid;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "asset")
@JsonBackReference
private AssetDetails assetDetails;
public AssetDetails getAssetDetails() {
return assetDetails;
}
public void setAssetDetails(AssetDetails assetDetails) {
this.assetDetails = assetDetails;
assetDetails.setAsset(this);
}
public Asset(your fields, AssetDetails assetDetails) {
super();
// your fields
this.assetDetails = assetDetails;
this.assetDetails.setAsset(this);
}
public Asset() {
super();
}
public BigInteger getAssetid() {
return assetid;
}
public void setAssetid(BigInteger assetid) {
this.assetid = assetid;
}
}
AssetDetails.java
@Entity
@Table(name="assetDetails")
public class AssetDetails {
@Id
@GeneratedValue
private BigInteger assetdetailid;
@JoinColumn(name = "assetid",nullable = false, updatable = false,referencedColumnName="assetid")
@OneToOne(cascade=CascadeType.ALL)
@JsonManagedReference
private Asset asset;
public Asset getAsset() {
return asset;
}
public void setAsset(Asset asset) {
this.asset = asset;
}
public AssetDetails(your fields,Asset asset) {
super();
//your fields
this.asset = asset;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.