Search code examples
javaspring-bootspring-data-jpafasterxmljackson-databind

How do I can bind an entity object to a local @Transient property?


EmployeeInfo entity class

@Entity
@Table(name = "employeeinfo")
public class EmployeeInfo{

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "employeeId")
private String employeeId;
@Column(name = "firstName")
private String firstName;
@Column(name = "middleName")
private String middleName;
@Column(name = "lastName")
private String lastName;

......

}

Another Entity class ProjectTaskComments

@Entity
@Table(name = "projecttaskcomments")
public class ProjectTaskComments{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Long id;
    @Basic(optional = false)
    @Column(name = "comments")
    private String comments;

    @Basic(optional = false)
    @Column(name = "commentTime")
    @Temporal(TemporalType.TIMESTAMP)
    private Date commentTime;
    @Column(name = "fkCommentedBy")
    private Long fkCommentedBy;


    @Transient
    @JsonIgnoreProperties
    private EmployeeInfo commentedEmployee;
    @Transient
    @Autowired
    EmployeeInfoService employeeInfoService; 


   public EmployeeInfo getCommentedEmployee() {
        EmployeeInfo employeeInfo;
        employeeInfo = employeeInfoService.getSingleEmployeeInfoByFkUserId(this.fkCommentedBy);
        if(employeeInfo != null) {
            this.commentedEmployee.setEmployeeId(employeeInfo.getEmployeeId());
            this.commentedEmployee.setFirstName(employeeInfo.getFirstName());
            this.commentedEmployee.setMiddleName(employeeInfo.getMiddleName());
            this.commentedEmployee.setLastName(employeeInfo.getLastName());
            this.commentedEmployee.setPhoto(employeeInfo.getPhoto());
            return commentedEmployee;
        } else {
            return null;
        }
    }

}

I tried to find an EmployeeInfo object in getCommentedEmployee() method by fkCommentedBy property and set to @Transient property commentedEmployee.

I found the following errors:

2018-10-11 13:07:56.834  WARN 16756 --- [nio-8081-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: (was java.lang.NullPointerException); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: java.util.ArrayList[1]->com.activeboss.model.pm.ProjectTasks["projecttaskcommentsCollection"]->org.hibernate.collection.internal.PersistentBag[0]->com.activeboss.model.pm.ProjectTaskComments["commentedEmployee"])
2018-10-11 13:07:56.853  WARN 16756 --- [nio-8081-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved exception caused by Handler execution: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: (was java.lang.NullPointerException); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: java.util.ArrayList[1]->com.activeboss.model.pm.ProjectTasks["projecttaskcommentsCollection"]->org.hibernate.collection.internal.PersistentBag[0]->com.activeboss.model.pm.ProjectTaskComments["commentedEmployee"])

How do I solve it?


Solution

  • The purpose of @Transient is to model a non persistent attribute, so it is unclear to me why do you want to @Transient on commentedByEmployee attribute when you have it persisted via "fkCommentedBy" attribute. IMO, @ManyToOne is more appropriate in this case.

    @Entity
    @Table(name = "projecttaskcomments")
    public class ProjectTaskComments {
    
    // .... other declarations 
    @ManyToOne
    @JoinColumn(name="fkCommentedBy")
    private EmployeeInfo commentedEmployee;
    // ..... other code
    }
    

    Now if you still want to use @Transient, then in the getter method you need to make sure that you have a valid referent to EmployeeInfoService object. @Autowired will not work here as the ProjectTaskComments is not a spring managed bean.