Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Hibernate在外键字段中插入空值_Java_Mysql_Hibernate_Spring Boot - Fatal编程技术网

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

Java 使用Hibernate在外键字段中插入空值,java,mysql,hibernate,spring-boot,Java,Mysql,Hibernate,Spring Boot,我有一个Question实体和Tag实体,具有getter、setter方法和OneToMany从Question到Tag的关系,以及OneToOne从Question到用户的关系 public class Question { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Long id; @Column(name="title") private String title

我有一个
Question
实体和
Tag
实体,具有getter、setter方法和
OneToMany
Question
Tag
的关系,以及
OneToOne
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 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() {

}
当我尝试使用邮递员插入问题时,请提供以下详细信息:

{
    "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\u id
tag\u id
插入空值

MySQL:


JSON和
@Entity
结构不匹配。JSON包含数字标识符,
@Entity
包含表示关系的实际对象。您很可能应该引入一个单独的DTO类来映射此JSON,而在
@Repository
中,您应该根据对象的id加载
User
Tag
对象或创建新对象。您已经有了
CascadeType.ALL
,因此Hibernate将级联持久化操作


通常,控制器层应该与存储库层分开,除非您正在做非常非常简单的事情。这有助于在不更改API契约的情况下改进服务,例如添加新列以审核更改。通过将
@Entity
暴露为数据,您的生活将更加艰难。

您应该在子实体外键列中添加referencedColumnName

referencedColumnName="your primaray key column name"
编辑:

referencedColumnName

  • 此外键列引用的列的名称
  • 与案例以外的实体关系映射一起使用时 此处所述,引用列位于目标的表中 实体
  • 当与单向OneToMany外键映射一起使用时 引用列位于源实体的表中
  • 在JoinTable注释中使用时,引用的键列为 在拥有实体的实体表中,如果 连接是反向连接定义的一部分
  • 在CollectionTable映射中使用时,引用的列位于 包含集合的实体的表
  • 默认值(仅在使用单个联接列时适用):相同 名称作为引用表的主键列
资产为父实体,资产明细为子实体 在这里,我采取了一对一的关系

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;
    }
}
@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;
    }   
}
AssetDetails.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;
    }
}
@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;
    }   
}

正如@Karol Dowbecki所建议的

将JSON转换为DTO对象,并使用该DTO从各自的存储库中获取
用户
标记
实体

最后创建问题实体对象并存储它

问题实体

@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;

}
标记实体

@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);

    }
}
测试类

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);

    }
}
@服务
公共类测试服务{
@自动连线
私人问题库;
@自动连线
私有用户存储库用户存储库;
@自动连线
私有标记库标记库;
公共无效添加问题(问题到问题){
Tag=null;
User=null;
问题=null;
设置标签=null;
tag=tagRepository.findById(dto.getTag());
tags=newhashset();
标签。添加(标签);
user=userRepository.findById(dto.getUser());
问题=新问题();
问题.设置标签(标签);
问题.设置用户(用户);
setId(dto.getId());
setBody(dto.getBody());
setTitle(dto.getTitle());
setViewCount(dto.getViewCount());
问题.setAnswerCount(dto.getAnswerCount());
setDateCreated(dto.getDateCreated());
questionRepository.save(问题);
}
}
注意
Question
Tag
之间的关系在
OneToMany
中,您必须使用
Collection
类型。

您的
对象中是否存在
用户
Tag
对象?它们是否已填充?在DB模式中,这些字段是否可以为空。。?你有id为1的用户和标记的记录吗?@Nuthan Kumar用户id和标记id在DB模式中可以为空。我有用户和id标签的记录1@ayrton我是否需要设置用户标记对象,而不是像我使用JoinColumn一样在REST调用中传递用户id和标记id?您可以尝试使用@OneToOne(mappedBy=“user\u id”)private user;如何从JSON对象获取id并将对象加载到存储库中?你能举个例子吗?谢天谢地!非常感谢。