簡體   English   中英

使用Hibernate在外鍵字段中插入空值

[英]Null values are inserted in the foreign key fields with Hibernate

我有一個Question實體和Tag實體,包含getter,setter方法和從questiontagOneToMany關系以及從questionuserOneToOne關系

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_idtag_id插入了空值。

MySQL的:

在此輸入圖像描述

正如@Karol Dowbecki建議的那樣,

將JSON轉換為DTO對象並使用該DTO從其各自的存儲庫中獲取UserTag實體。

最后創建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);

    }
}

注意QuestionTag之間的關系是在OneToMany您必須使用Collection類型。

您在JSON和@Entity結構之間存在不匹配。 JSON包含數字標識符,而@Entity包含表示關系的實際對象。 您最有可能應該引入一個單獨的DTO類來映射此JSON,而在@Repository您應該根據其ID加載UserTag對象或創建新對象。 你已經有CascadeType.ALL所以Hibernate會級聯持久化操作。

通常,控制器層應該與存儲庫層分開,除非您正在做非常非常簡單的事情。 這有助於在不更改API合同的情況下改進服務,例如添加新列以進行審計更改。 通過將@Entity暴露為DTO,您將使您的生活更加艱難。

您應該在子實體外鍵列中添加referencedColumnName

referencedColumnName="your primaray key column name"

編輯:

referencedColumnName

  • 此外鍵列引用的列的名稱。
  • 當與此處描述的情況之外的實體關系映射一起使用時,引用的列位於目標實體的表中。
  • 與單向OneToMany外鍵映射一起使用時,引用的列位於源實體的表中。
  • 在JoinTable注釋中使用時,引用的鍵列位於擁有實體的實體表中,如果連接是反連接定義的一部分,則為反向實體。
  • 在CollectionTable映射中使用時,引用的列位於包含該集合的實體的表中。
  • 默認值(僅在使用單個連接列時適用):與引用表的主鍵列相同的名稱。

資產是父實體,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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM