如何在休眠状态下保持单向一对多关系

时间:2018-08-09 00:08:44

标签: java hibernate jpa hibernate-onetomany

我尝试使用一组项目(一组 Item 实体)持久化 ProviderQuote 实体,但出现此错误:

java.sql.SQLException: Field 'fk_provider_quote$item' doesn't have a default value
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:964) ~[mysql-connector-java-5.1.44.jar:5.1.44]
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3973) ~[mysql-connector-java-5.1.44.jar:5.1.44]
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3909) ~[mysql-connector-java-5.1.44.jar:5.1.44]
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2527) ~[mysql-connector-java-5.1.44.jar:5.1.44]
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2680) ~[mysql-connector-java-5.1.44.jar:5.1.44]
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2487) ~[mysql-connector-java-5.1.44.jar:5.1.44]
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1858) ~[mysql-connector-java-5.1.44.jar:5.1.44]
    at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2079) ~[mysql-connector-java-5.1.44.jar:5.1.44]
    at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2013) ~[mysql-connector-java-5.1.44.jar:5.1.44]
    at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5104) ~[mysql-connector-java-5.1.44.jar:5.1.44]
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1998) ~[mysql-connector-java-5.1.44.jar:5.1.44]
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:204) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.dialect.identity.GetGeneratedKeysDelegate.executeAndExtract(GetGeneratedKeysDelegate.java:57) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]

这是我模型的兴趣部分:

enter image description here

这是我所做的映射:

工作实体:

@Entity
@Table(name="work")
@Getter
@Setter
@JsonIdentityInfo(
          generator = ObjectIdGenerators.PropertyGenerator.class, 
          property = "id")
public class Work implements Serializable{

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy= GenerationType.AUTO, generator="native")
    @GenericGenerator(name = "native", strategy = "native")
    @Column(name="id_work")
    private int id;

    @Column(name="work_number")
    private String workNumber;

    @Column(name="provider_label")
    private String providerLabel;

    @Column(name="user_label")
    private String userLabel;

    @Column(name="creation_date")
    private Date creationDate;

    @Enumerated(EnumType.STRING)
    @Column(name="state")
    private State state;

    @Column(name="state_changes")
    private String historyStateChanges;

    @Column(name="comment")
    private String comment;

    @ManyToOne
    @JoinColumn(name="fk_user$work")
    private User user;

    @ManyToOne
    @JoinColumn(name="fk_provider$work")
    private Provider provider;

    @OneToOne(mappedBy = "work", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    private Contract contract;

    @OneToMany(mappedBy="work", cascade = CascadeType.ALL)
    private Set<Visit> visits;

    @OneToOne(mappedBy = "work", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    private OnlineQuote onlineQuote;

    @OneToOne(mappedBy = "work", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    private ProviderQuote providerQuote;

    @OneToOne(fetch=FetchType.LAZY, cascade = CascadeType.ALL, optional = false)
    @PrimaryKeyJoinColumn
    private Review review;


    public Work() {

    }   
}

ProviderQuote实体:

@Entity
@Table(name="provider_quote")
@Getter
@Setter
public class ProviderQuote {

    @Id
    private int id;

    @Column(name="quotation_number")
    private String number;

    @Column(name="date")
    private Date date;

    @Column(name="clarifications")
    private String clarifications;

    @Column(name="subtotal")
    private double subtotal;

    @Column(name="administration_fee")
    private double administrationFee;

    @Column(name="total")
    private double total;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "fk_provider_quote$item")
    private Set<Item> items;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="pk_work$provider_quote")
    @MapsId
    private Work work;

}

项目实体:

@Entity
@Table(name="item")
@Getter
@Setter
public class Item {

    @Id
    @GeneratedValue(strategy= GenerationType.AUTO, generator="native")
    @GenericGenerator(name = "native", strategy = "native")
    @Column(name="id_item")
    private int id;

    @Column(name="name")
    private String name;

    @Column(name="value")
    private double value;

    @Column(name="duration_value")
    private double durationValue;

    @Column(name="duration_time")
    private String durationTime;

    @Column(name="warranty_value")
    private double warrantyValue;

    @Column(name="warranty_time")
    private String warrantyTime;

    @Column(name="work_description")
    private String workDescription;

    @Column(name="warranty_description")
    private String warrantyDescription;

    @Column(name="image")
    private String image;

    @Column(name="comment")
    private String comment;
}

这是我尝试保留 ProviderQuote 实体的部分:

@RequestMapping(value = "/provider_quotes", method = RequestMethod.POST, headers = "Accept=application/json")
@ResponseBody
@Transactional
public ResponseEntity<String> createProviderQuote(@Valid @DTO(ProviderQuoteDto.class) ProviderQuote providerQuote,
        @RequestParam(value = "work", required = true) String workId,
        UriComponentsBuilder uriComponentsBuilder, final HttpServletRequest request) {

    Work work=workService.findWorkById(Integer.parseInt(workId));
    providerQuote.setWork(work);
    work.setProviderQuote(providerQuote);
    providerQuote=providerQuoteService.createProviderQuote(providerQuote);
    return new ResponseEntity<>("Ok", HttpStatus.OK);
}

为澄清此代码,我所拥有的是一个控制器,该控制器接收一个 ProviderQuote 实体,该实体带有必须保留在数据库中的项目列表。当我尝试将ProviderQuote实体与项目列表保持一致时,会出现问题,因为如果执行此操作:

providerQuote.setItems(null);

它可以正常工作。我的问题是为什么会发生这种情况,我该怎么做才能将 ProviderQuote 实体保留在项目列表中?

非常感谢!

0 个答案:

没有答案