【问题标题】:JPA doesn't save the Associated Object in Object gotten by @RequestBody annotationJPA 不会将关联对象保存在 @RequestBody 注释获取的对象中
【发布时间】:2019-05-14 05:13:01
【问题描述】:

以下是Developer 实体。

  • Developer
@Entity
@Getter
@Setter
public class Developer {
    @Id
    @GeneratedValue
    @Column(name="DEVELOPER_ID")
    private Long id;

    private String nickname;
    private String name;
    private String imageURI;

    @OneToMany(mappedBy = "developer", cascade={CascadeType.PERSIST})
    private List<Article> articleList = new ArrayList<>();

    public void addArticle(Article article) {
        this.articleList.add(article);

        if ( article.getDeveloper() != this )
            article.setDeveloper(this);
    }

}

以下是Article实体。

  • Article
@Entity
@Getter
@Setter
public class Article {
    @Id
    @GeneratedValue
    @Column(name="ARTICLE_ID")
    private Long id;

    private String subject;

    @ElementCollection
    private List<String> contents = new ArrayList<>();

    public void addContent(String content) {
        this.contents.add(content);
    }

    @ManyToOne
    @JoinColumn(name="DEVELOPER_ID")
    private Developer developer;

    public void setDeveloper(Developer developer) {
        this.developer = developer;

        if ( !developer.getArticleList().contains(this) )
            developer.getArticleList().add(this);
    }

}

通过 ajax 查看对 RestController (/about/developers/rest/add) 的请求。 以下是Request Body的json。

  • 请求正文 json
    [
    {"articleList":[
        {"contents":["article line","article line"],
        "subject":"article subject"},
        {"contents":["article line","article line","article line"],
        "subject":"article subject"}
     ],
    "nickname":"dev nickname",
    "name":"(dev name)",
    "imageURI":"default.png"
    },

    {"articleList":[
        {"contents":["article line","article line"],
        "subject":"article subject"},
        {"contents":["article line"],
        "subject":"article subject"}
     ],
    "nickname":"dev nickname",
    "name":"(dev name)",
    "imageURI":"default.png"}
    ]

包含@RequestBody的RestController

  • RestController
@RestController
@RequestMapping("/about")
public class AboutRestController {

    @Autowired
    private DeveloperService developerService;

    @PostMapping("/developers/rest/add")
    public void developersRegisterAPI(@RequestBody List<Developer> developerList) {

        /** Not Working **/
        // Saving Developer only (except Associated Articles)
        for (Developer developer : developerList) {
            developerService.save(developer);
        }


        /** Working **/
        // Saving Developers and Associated Articles
        for (Developer developer : developerList) {

            Developer newDeveloper = new Developer();
            newDeveloper.setName(developer.getName());
            newDeveloper.setImageURI(developer.getImageURI());
            newDeveloper.setNickname(developer.getNickname());

            for (Article article : developer.getArticleList()) {

                Article newArticle = new Article();
                newArticle.setSubject(article.getSubject());
                newArticle.setContents(article.getContents());
                newDeveloper.addArticle(newArticle);

            }

            developerService.save(newDeveloper);
        }
    }

}

当我打印@RequestBody List&lt;Developer&gt; developerList 时,每个Developer 对象都有关联的Article 对象。

在第一种情况下(无法正常工作,developerService.save(developer);),developerService.findAll() 的结果仅包括 Developer 对象。检索到的 Developer 对象中没有 Article 对象。

在第二种情况下(正常工作,developerService.save(newDeveloper);),developerService.findAll() 的结果包括Developer 对象和关联的Article 对象。

事实上,这两种情况都是在 RestController 的方法中保存关联的Articles。 但是在web控制器的方法中,当我使用developerService.findAll()时,没有文章。因此,如果我通过Model 传递检索到的Developer 对象,则没有关联的Article 并且视图无法打印这些对象。

以下是DeveloperService

  • DeveloperServiceDeveloperRepository
@Service
public class DeveloperService {
    @Autowired
    DeveloperRepository developerRepository;

    public void save(Developer developer) {
        developerRepository.save(developer);
    }

    public void delete(Developer developer) {
        developerRepository.delete(developer);
    }

    public List<Developer> findAll() {
        return developerRepository.findAll();
    }
}
@Repository
@Transactional
public interface DeveloperRepository extends JpaRepository<Developer, Long> {
}

以下是ARTICLEh2-console中的表

ARTICLE Table in h2-console (click me for image)

如您所见,DEVELOPER_ID 为空。

我可以只用解决这个问题吗

        for (Developer developer : developerList) {
            developerService.save(developer);
        }

?

【问题讨论】:

    标签: java spring-data-jpa thymeleaf


    【解决方案1】:

    first 不起作用,因为在 json 中的文章列表中没有绑定开发者对象。由于这条线,第二种情况正在起作用

        newDeveloper.addArticle(newArticle);
    

    您要添加的位置 如果(文章.getDeveloper()!=这个) article.setDeveloper(this); 尝试在第一个循环中绑定您的文章列表中的开发人员对象,您的代码将起作用。我的意思是尝试在列表中的每个文章对象中绑定开发者对象

    【讨论】:

    • 这是有道理的。 newDeveloper.addArticle(newArticle); 和 MessageConverter 制作的对象之间有区别吗?这些对象具有相同的值。但坚持后,在 ARTICLE 表中,newDeveloper.addArticle(newArticle); 具有“DEVELOPER_ID”,而 MessageConverter 对象没有(空值)。
    猜你喜欢
    • 1970-01-01
    • 2016-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多