在mysql

时间:2018-11-18 09:06:27

标签: java mysql spring hibernate jpa

我的模型班有:

  

LetterDoc.java

@Entity
@Table(name = "letter_doc")
public class LetterDoc implements Serializable {


    private static final long serialVersionUID = 1L;

    @Id
    TwoP twoP;


    private String docFile;

    //i ommited getters and setters
    public LetterDoc() {

    }
  

Document.java

@Entity
@Table(name = "document")
public class Document {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long docId;

    private String docName;

    @Transient
    private boolean checked=false;

    public Document() {

    }
  

TwoP.java

@Embeddable
public class TwoP implements Serializable {

    @ManyToOne(fetch = FetchType.EAGER, optional = false,cascade=CascadeType.PERSIST)
    @JoinColumn(name = "letterNo",unique=true)
    @JsonIgnore
    private Letter letter;

    @ManyToOne(fetch = FetchType.EAGER, optional = false,cascade=CascadeType.PERSIST)
    @JoinColumn(name = "documentId",unique=true)
    @JsonIgnore
    private Document document;

    public TwoP(Letter letter, Document document) {

        this.letter = letter;
        this.document = document;
    }

    public TwoP() {

    }


}

我从客户端发送到我的api中的json数据是:

enter image description here

在我的api中,我使用了这种方法来消耗json数据:

@PostMapping(value = "/letter/create", produces = MediaType.APPLICATION_JSON_VALUE)
    public SLDto postAllOne(@RequestBody SLDto sldto) {

Letter letter = letterRepository.save(new Letter(clkLetter, sldto.getLetterDto().getInOut(),
                sldto.getLetterDto().getInOutNo(), sldto.getLetterDto().getInOutDate(),
                sldto.getLetterDto().getLetterIssuedSubBy(), sldto.getLetterDto().getLetterFile(),
                sldto.getLetterDto().getRepresentativeName(), selection, assessment));
    //Please consider letter is inserted with Id no 22.

            for (DocumentDto documentDto : sldto.getDocumentDto()) {
                TwoP twoP = null;
                LetterDoc letterDoc = null;

                System.out.println("loopedonce");
                Document document = null;
                System.out.println("total documents Id is" + documentDto.getDocId());
                document = documentRepository.findById((long) documentDto.getDocId()).get();
                System.out.println("Document Id from db is" + document.getDocId());
                twoP = new TwoP(letter, document);
                letterDoc = new LetterDoc();
                letterDoc.setTwoP(twoP);
                letterDoc.setDocFile(null);
                letterDocRepository.save(letterDoc);
                     } 
}

SlDto.java类

private LetterDto letterDto;
    private List<DocumentDto> documentDto;
    private List<SelectionCustomOfficeDto> selectionCustomOfficeDto;

现在在我上面使用的 For循环中,必须将其循环两次,因为传入的Json数据的数量为2。是的,它循环了两次,在此行document = documentRepository.findById((long) documentDto.getDocId()).get();中,我两次获取Document对象,但是将其插入 letterDocRepository.save(letterDoc); 时,它向我显示

  

键“ UK_5pahc9x5lwh5k4owpm3vjfq3c”的条目“ 22”重复

'22'是我在“字母”表中插入时创建的近期ID

由于我的 documentDto.getDocId()返回了来自JSON数据的1,2,尽管它们不同,但是程序向我显示错误。

还要查看正在发生的事情,我调试了它们以查看数据是否从数据库中以以下方式到达:

enter image description here

错误是:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '22' for key 'UK_5pahc9x5lwh5k4owpm3vjfq3c'
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_161]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) ~[na:1.8.0_161]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) ~[na:1.8.0_161]
    at java.lang.reflect.Constructor.newInstance(Unknown Source) ~[na:1.8.0_161]
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) ~[mysql-connector-java-5.1.47.jar:5.1.47]
    at com.mysql.jdbc.Util.getInstance(Util.java:408) ~[mysql-connector-java-5.1.47.jar:5.1.47]
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:936) ~[mysql-connector-java-5.1.47.jar:5.1.47]

1 个答案:

答案 0 :(得分:1)

我认为您的问题出在Cascade属性行为上,Persist会在您保存letterDoc对象时尝试将其插入。 尝试改用cascade.MERGE

如果您希望拥有持久性,请不要插入您用cascade.persist声明的任何关联,因为Hibernate会为您这样做。