0

I try to map dto to an entity with avoiding complex objects but I have a null exception when I try to save my article entity?? in my ArticleRequest instead of using Department & ArticleCategory as a full object I just put their ids (uid) .

Here is my ArticleRequest:

@Slf4j
@Builder
@Data
public class ArticleRequest {

    private Long id;

    @Size(min = 32, message = "uid should have at least 32 characters")
    private String uid;

    @Size(min = 2, message = "title should have at least 2 characters")
    private String title;

    @NotBlank(message = "content should not be empty value")
    private String content;

    @NotNull(message = "article category id should not be null value")
    private String articleCategoryUid;

    @NotNull(message = "department id should not be empty value")
    private String departmentUid;

    @JsonIgnore
    private List<ArticleVote> articleVoteList;

    public static ArticleRequest fromEntity(Article article) {
        if (article == null) {
            log.warn("Class: ArticleRequest || Method: fromEntity() || Error: article is null!!!");
            return null;
        }

        return ArticleRequest.builder()
                .id(article.getId())
                .uid(article.getUid())
                .title(article.getTitle())
                .content(article.getContent())
                .articleCategoryUid(article.getArticleCategory().getUid())
                .departmentUid(article.getDepartment().getUid())
                .build();

    }

    public static Article toEntity(ArticleRequest articleRequest) {
        if (articleRequest == null) {
            log.warn("Class: ArticleRequest || Method: toEntity() || Error: articleRequest is null!!!");
            return null;
        }

        Article article = new Article();
        article.setId(articleRequest.getId());
        article.setUid(articleRequest.getUid());
        article.setTitle(articleRequest.getTitle());
        article.setContent(articleRequest.getContent());
        article.getArticleCategory().setUid(articleRequest.getArticleCategoryUid()); // i have null exeption here !! because ArticleCategory already null
         article.getDepartment().setUid(articleRequest.getDepartmentUid()); // i have null exeption here !! because Department already null
        return article;
    }
}

here is my baseEntity

@Data
@NoArgsConstructor
@AllArgsConstructor
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class BaseEntity implements Serializable {

    //region Simple Properties

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false, updatable = false)
    private Long id;

    @NotNull
    @Size(min = 32, message = "uid should have at least 32 characters")
    @Column(name = "uid", nullable = true,updatable = false)
    private String uid;

    //endregion

}

here is my article category class

@Data
@Entity
@Table(name = "article_categories", schema = "public")
public class ArticleCategory extends BaseEntity {

    //region Simple Properties

    @NotNull
    @Size(min = 2, message = "name should have at least 2 characters")
    @Column(name = "name")
    private String name;

    @NotNull
    @Size(min = 2, message = "slug should have at least 2 characters")
    @Column(name = "slug")
    private String slug;

    @NotNull
    @Size(min = 2, message = "description should have at least 2 characters")
    @Column(name = "description")
    private String description;

    //endregion

    //region Complex Properties
    @JsonIgnore
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "articleCategory", orphanRemoval = true)
    private List<Article> articleList;
    //endregion}

here is my department class

@Data
@Entity
@Table(name = "departments", schema = "public")
public class Department extends BaseEntity {

    //region Simple Properties
    @Size(min = 2,message = "name should have at least 2 characters")
    @Column(name = "name")
    private String name;

    @Enumerated(EnumType.STRING)
    @Column(name = "status")
    private DepartmentStatusEnum status;

    //endregion

    //region Complex Properties

    @JsonIgnore
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "department", orphanRemoval = true)
    private List<Article> articleList;
}

and here is my service

@Override
    public ArticleRequest saveArticle(ArticleRequest articleRequest) {
        if (articleRequest == null) {
            throw new InvalidEntityException(CustomErrorMessage.ARTICLE_CAN_NOT_BE_NULL.getMessage(), CustomErrorCodes.ARTICLE_NOT_VALID);
        }
        articleRequest.setUid(UUID.randomUUID().toString());
        Article saveArticle=ArticleRequest.toEntity(articleRequest);// null exception
        Article newArticle = articleRepository.save(saveArticle);
        ArticleRequest newArticleRequest = ArticleRequest.fromEntity(newArticle);
        return newArticleRequest;
    }

so how I can save my article entity & pass uid of articleCategory and department with the right way!

thanks in advance.

  • 1
    You could create an new instance of ArticleCategory and Departement before set their ids. Try to look https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it – sigur Dec 09 '21 at 09:28
  • Does this answer your question? [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – xerx593 Dec 10 '21 at 14:10

2 Answers2

1

Informations given dont give a great idea , you should past the class Department and Article in your question

Probably your problem is here :

article.getArticleCategory().setUid(articleRequest.getUid()); article.getDepartment().setUid(articleRequest.getUid());

You should set the ArticleCategory and the Department of your article , creating a new objtects and setting them . I think the solution is replacing these lines with :

article.setArticleCategory(new ArticleCategory());
article.getArticleCategory().setUid(articleRequest.getArticleCategoryUid()); 
article.setDepartment(new Department());
article.getDepartment().setUid(articleRequest.getDepartmentUid());


TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing

You should save or persist the Properties values in the database ( instances ) before the persistance of the Article object, so the code will be like that :

ArticleCategory ac = new ArticleCategory();
ac.setUid(articleRequest.getArticleCategoryUid());// if you need you can set the other properties of the ac , get them from the articleRequest
articleCategoryRepository.save(ac);
Department dep = new Department();
dep.setUid(articleRequest.getDepartmentUid());
departmentRepository.save(dep);
article.setArticleCategory(ac);
article.setDepartment(dep);
articleRepository.save(article);
Oussama ZAGHDOUD
  • 1,767
  • 5
  • 15
  • i update my post (adding articlecategory and department classess) now i have ne error : TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing – Ouakala Abdelaaziz Dec 09 '21 at 14:05
  • 1
    https://stackoverflow.com/questions/2302802/how-to-fix-the-hibernate-object-references-an-unsaved-transient-instance-save @NevergiveupNever – Oussama ZAGHDOUD Dec 10 '21 at 09:39
  • I was into this article before but it didn't help me!!! when i use id the save is works but when i choose to use uid filed it show me this error if i change the cascade type, i find a duplicate in the database! any suggestions i will appreciate – Ouakala Abdelaaziz Dec 10 '21 at 12:51
  • 1
    @NevergiveupNever answer updated , is that what are you looking for ? – Oussama ZAGHDOUD Dec 10 '21 at 13:44
0
article.getArticleCategory() //this gives you the NPE

Initialize articleCategory before you call the getter method of it.

E.g:

article.setArticleCategory(new ArticleCategory());

Its the same for department. Initialize department object before you call getDepartment()

whoami
  • 1,517
  • 1
  • 21
  • 29
  • i do the initialization but i have new error says TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing – Ouakala Abdelaaziz Dec 09 '21 at 14:06