Hybernate ManyToOne属性未更新

问题描述

我无法通过更新InfoLinks来更新Info一个Info可以包含多个InfoLinkInfoLink不必在Info上具有引用。

sql

CREATE TABLE INFO (
    INFO_ID       NUMBER(19,0) NOT NULL PRIMARY KEY,CREATION_DATE DATE     NOT NULL,LABEL         VARCHAR2(100 CHAR),TEXT          VARCHAR2(2500 CHAR),UPDATE_DATE   TIMESTAMP     NOT NULL
) TABLESPACE @db.tablespace.data@;

CREATE SEQUENCE SEQ_INFO;

CREATE TABLE INFO_LINK (
    INFO_LINK_ID       NUMBER(19,INFO_ID NUMBER(19,0),CREATION_DATE DATE NOT NULL,LINK VARCHAR2(1000 CHAR),UPDATE_DATE   TIMESTAMP NOT NULL,CONSTRAINT LINK_INFO_FK foreign key (INFO_ID)
    references INFO(INFO_ID)
) TABLESPACE @db.tablespace.data@;

CREATE SEQUENCE SEQ_INFO_LINK;

信息实体:

@Entity
@Table(name = "INFO")
public class Info implements Serializable {

    public static final String SEQUENCE_NAME = "SEQ_INFO";

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = SEQUENCE_NAME)
    @SequenceGenerator(name = SEQUENCE_NAME,sequenceName = SEQUENCE_NAME,allocationSize = 1)
    private Long infoId;

    @Size(max = 100)
    @NotBlank
    private String label;

    @NotNull
    private String text;

    @OnetoMany(mappedBy="info",cascade = CascadeType.MERGE,orphanRemoval = true)
    private List<InfoLink> infoLinks;

    @NotNull
    private LocalDate creationDate;

    @NotNull
    private LocalDateTime updateDate;

    protected Info() {
        //for jpa
    }

    public Info(String label,String text,List<InfoLink> infoLinks) {
        Assert.hasText(label,"label is blank");
        this.label = label;
        this.text = text;
        this.infoLinks = infoLinks;
        this.creationDate = LocalDate.Now();
        this.updateDate = LocalDateTime.Now();
    }

    public void update(String label,"label is blank");
        Assert.isTrue(text != null,"info is null");

        this.label = label;
        this.text = text;
        this.infoLinks.clear();
        if (infoLinks != null) {
            this.infoLinks.addAll(infoLinks);
        }
    }
}

InfoLink ENTITY:

@Entity
@Table(name = "INFO_LINK")
public class InfoLink implements Serializable {

    public static final String SEQUENCE_NAME = "SEQ_INFO_LINK";

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE,allocationSize = 1)
    private Long infoLinkId;

    @ManyToOne()
    @JoinColumn(name="INFO_ID",nullable=false)
    private Info info;

    @Size(max = 1000)
    @NotBlank
    private String link;

    @NotNull
    private LocalDate creationDate;

    @NotNull
    private LocalDateTime updateDate;

    protected InfoLink() {
        //for jpa
    }

    public InfoLink(Long infoLinkId,String link) {
        Assert.hasText(link,"link is blank");
        this.infoLinkId = infoLinkId;
        this.link = link;
        this.creationDate = LocalDate.Now();
        this.updateDate = LocalDateTime.Now();
    }

    public void update(String link) {
        Assert.hasText(link,"link is blank");

        this.link = link;
    }
}

InfoDTO:

public class InfoDto {

    private Long infoId;
    private String label;
    private LocalDate date;
    private String text;
    private List<InfoLinkDto> infoLinks;

    private InfoDto() {
    }

    public InfoDto(Long infoId,String label,LocalDate date,List<InfoLinkDto> infoLinks) {
        this.infoId = infoId;
        this.label = label;
        this.date = date;
        this.text = text;
        this.infoLinks = infoLinks;
    }
}

InfoLinkDto:

public class InfoLinkDto {

    private Long infoLinkId;
    private Long infoId;
    private String link;

    private InfoLinkDto() {
    }

    public InfoLinkDto(Long infoLinkId,Long infoId,String link) {
        this.infoLinkId = infoLinkId;
        this.infoId = infoId;
        this.link = link;
    }
}

InfoAssembler:

public class InfoAssembler {

    private InfoAssembler() {
    }

    public static Info toInfo(InfoDto infoDto) {
        List<InfoLink> infoLinkList = new ArrayList<>();
        if (infoDto.getInfoLinks() != null) {
            for(InfoLinkDto link : infoDto.getInfoLinks()) {
                infoLinkList.add(new InfoLink(link.getInfoLinkId(),link.getLink()));
            }
        }
        
        return new Info(infoDto.getLabel(),infoDto.getText(),infoLinkList);
    }

    public static InfoDto toInfoDto(Info info) {
        return new InfoDto(info.getInfoId(),info.getLabel(),info.getCreationDate(),info.getText(),info.getInfoLinks().stream().map(infoLink -> toInfoLinkDto(infoLink)).collect(Collectors.toList()));
    }

    public static List<InfoDto> toInfoDtoList(List<Info> infos) {
        return infos.stream().map(info -> toInfoDto(info)).collect(Collectors.toList());
    }

    public static InfoLinkDto toInfoLinkDto(InfoLink infoLink) {
        return new InfoLinkDto(infoLink.getInfoLinkId(),new Long(21),infoLink.getLink());
    }
}

服务中的更新方法

@Override
    @Transactional
    public void update(Long infoId,InfoDto infoDto) throws InfoNotFoundException {
        final Info info = infoRepository.findOne(infoId);
        if(info == null) {
            throw new InfoNotFoundException(infoId);
        }
        Info updatedInfo = InfoAssembler.toInfo(infoDto);

        info.update(updatedInfo.getLabel(),updatedInfo.getText(),infoDto.getInfoLinks().stream().map(infoLink -> new InfoLink(infoLink.getInfoLinkId(),infoLink.getLink())).collect(Collectors.toList()));
    }

因此,如果我删除Info,则所有InfoLinks都将被删除到DB上。但是通过InfoDto更新只会更新InfoLink。

知道我可能做错了什么吗?非常感谢!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)