Hibernate One To Many创建方法

时间:2017-08-16 14:34:56

标签: java hibernate jpa

从控制器保存父实体时出现问题。子对象未保存到数据库中。我得到了#34; subject_id"从短语表不能为空。我在这里做错了什么,什么是合适的解决办法?我是否需要将DTO对象用于实体类,或者我的方法是否合适? Bellow是表,java实体和控制器服务。请指教!?

-- parent table
CREATE TABLE subjects
(
subject_id                Bigint NOT NULL AUTO_INCREMENT,
name                      Varchar(250) NOT NULL,
weight                    Int,
color                     Varchar(20),
ontology_id               Bigint NOT NULL,
created_by                Bigint NOT NULL,
created_at                Datetime NOT NULL,
updated_by                Bigint,
updated_at                Datetime, 
PRIMARY KEY               (subject_id)
);

-- child table
CREATE TABLE phrases
(
phrase_id                 Bigint NOT NULL AUTO_INCREMENT,
name                      Varchar(250) NOT NULL,
weight                    Int,
color                     Varchar(20),
subject_id                Bigint NOT NULL,
created_by                Bigint NOT NULL,
created_at                Datetime NOT NULL,
updated_by                Bigint,
updated_at                Datetime, 
PRIMARY KEY               (phrase_id)
);

ALTER TABLE phrases ADD CONSTRAINT phrases_subjects_fk FOREIGN KEY (subject_id) REFERENCES subjects (subject_id);


@JsonIgnoreProperties(ignoreUnknown = true)
@Entity
@Table(name = "subjects")
public class Subject implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "subject_id")
    private Long subjectId;

    @NotEmpty
    @Size(max = 250)
    @Column(name = "name", length = 250, nullable = false)
    private String name;

    @NotNull
    @Column(name = "weight")
    private Integer weight;

    @Size(max = 20)
    @Column(name = "color", length = 20)
    private String color;

    @NotNull
    @Column(name = "ontology_id")
    private Long ontologyId;

    @OneToMany(mappedBy = "subject", targetEntity = Phrase.class, fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
    private Set<Phrase> phrases;

    @Column(name = "created_by")
    private Long createdBy;

    @JsonIgnore
    @CreationTimestamp
    @Column(name = "created_at")
    @Temporal(TemporalType.TIMESTAMP)
    private Date createdAt;

    @Column(name = "updated_by")
    private Long updatedBy;

    @JsonIgnore
    @UpdateTimestamp
    @Column(name = "updated_at")
    @Temporal(TemporalType.TIMESTAMP)
    private Date updatedAt;

    public Subject() {
        // empty constructor
    }

    public Subject(@JsonProperty(value = "subjectId") Long subjectId,
            @JsonProperty(value = "name") String name,
            @JsonProperty(value = "weight") Integer weight,
            @JsonProperty(value = "color") String color,
            @JsonProperty(value = "ontologyId") Long ontologyId,
            @JsonProperty(value = "phrases") Set<Phrase> phrases,
            @JsonProperty(value = "createdBy") Long createdBy,
            @JsonProperty(value = "updatedBy") Long updatedBy) {
        super();
        this.subjectId = subjectId;
        this.name = name;
        this.weight = weight;
        this.color = color;
        this.ontologyId = ontologyId;
        this.phrases = phrases;
        this.createdBy = createdBy;
        this.updatedBy = updatedBy;
    }

    public Long getSubjectId() {
        return subjectId;
    }

    public void setSubjectId(Long subjectId) {
        this.subjectId = subjectId;
    }

    public String getName() {
        return name;
    }

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

    public Integer getWeight() {
        return weight;
    }

    public void setWeight(Integer weight) {
        this.weight = weight;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public Long getOntologyId() {
        return ontologyId;
    }

    public void setOntologyId(Long ontologyId) {
        this.ontologyId = ontologyId;
    }

    public Set<Phrase> getPhrases() {
        return phrases;
    }

    public void setPhrases(Set<Phrase> phrases) {
        this.phrases = phrases;
    }

    public Long getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(Long createdBy) {
        this.createdBy = createdBy;
    }

    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    public Long getUpdatedBy() {
        return updatedBy;
    }

    public void setUpdatedBy(Long updatedBy) {
        this.updatedBy = updatedBy;
    }

    public Date getUpdatedAt() {
        return updatedAt;
    }

    public void setUpdatedAt(Date updatedAt) {
        this.updatedAt = updatedAt;
    }





}

package com.gda.wControl.domain;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import org.hibernate.validator.constraints.NotEmpty;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.fasterxml.jackson.annotation.JsonProperty;

@JsonIgnoreProperties(ignoreUnknown = true)
@Entity
@Table(name = "phrases")
public class Phrase implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -5778951738523949512L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "phrase_id")
    private Long phraseId;

    @NotEmpty
    @Size(max = 250)
    @Column(name = "name", length = 250, nullable = false)
    private String name;

    @NotNull
    @Column(name = "weight")
    private Integer weight;

    @Size(max = 20)
    @Column(name = "color", length = 20)
    private String color;

    @ManyToOne
    @JoinColumn(name = "subject_id", referencedColumnName = "subject_id")
    private Subject subject;

    @Column(name = "created_by")
    private Long createdBy;

    @JsonIgnore
    @CreationTimestamp
    @Column(name = "created_at")
    @Temporal(TemporalType.TIMESTAMP)
    private Date createdAt;

    @Column(name = "updated_by")
    private Long updatedBy;

    @JsonIgnore
    @UpdateTimestamp
    @Column(name = "updated_at")
    @Temporal(TemporalType.TIMESTAMP)
    private Date updatedAt;

    public Phrase() {
        // empty constructor
    }

    public Phrase(@JsonProperty(value = "phraseId") Long phraseId,
            @JsonProperty(value = "name") String name,
            @JsonProperty(value = "weight") Integer weight,
            @JsonProperty(value = "color") String color,
            @JsonProperty(value = "subject") Subject subject,
            @JsonProperty(value = "createdBy") Long createdBy,
            @JsonProperty(value = "updatedBy") Long updatedBy) {
        super();
        this.phraseId = phraseId;
        this.name = name;
        this.weight = weight;
        this.color = color;
        this.subject = subject;
        this.createdBy = createdBy;
        this.updatedBy = updatedBy;
    }

    public Long getPhraseId() {
        return phraseId;
    }

    public void setPhraseId(Long phraseId) {
        this.phraseId = phraseId;
    }

    public String getName() {
        return name;
    }

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

    public Integer getWeight() {
        return weight;
    }

    public void setWeight(Integer weight) {
        this.weight = weight;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public Subject getSubject() {
        return subject;
    }

    public void setSubject(Subject subject) {
        this.subject = subject;
    }

    public Long getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(Long createdBy) {
        this.createdBy = createdBy;
    }

    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    public Long getUpdatedBy() {
        return updatedBy;
    }

    public void setUpdatedBy(Long updatedBy) {
        this.updatedBy = updatedBy;
    }

    public Date getUpdatedAt() {
        return updatedAt;
    }

    public void setUpdatedAt(Date updatedAt) {
        this.updatedAt = updatedAt;
    }




}

@ApiOperation(value = "add a new subject")
@RequestMapping(value = "/add", method = RequestMethod.POST)
public Subject addSubject(@Valid @RequestBody Subject Subject) {
    return subjectService.createSubject(Subject);
}

public Subject createSubject(Subject subject) {

    Subject existingSubject = subjectRepository.findByNameAndOntologyId(
            subject.getName().toLowerCase(), subject.getOntologyId());

    if (existingSubject != null) {
        throw new ValidationException(String.format(SUBJECT_ALREADY_EXIST,
                subject.getName(), subject.getOntologyId()));
    }

    return subjectRepository.saveAndFlush(subject);
}

我用getter和setter更新了这个类。当我传递给@RequestBody时,我得到以下JSON

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:Column&#39; subject_id&#39;不能为空

JSON

{

  "name": "string444",
  "weight": 0,
  "color": "string",
  "ontologyId": 1,
  "phrases": [
    {    
      "name": "string",
      "weight": 0,
      "color": "string",
      "createdBy": 1
    }
  ],
  "createdBy": 1
}

1 个答案:

答案 0 :(得分:0)

看起来未在主题(父)对象中设置短语(子)对象。这听起来像是一个API调用。无论谁传递此信息并尝试添加主题,都不会设置客户端对象。

我还注意到setPhrases settter在Subject实体中不可用。

请确保您具有setter方法来设置子对象,并确保传递主题对象的人设置了子对象。