【问题标题】:How do I can bind an entity object to a local @Transient property?如何将实体对象绑定到本地 @Transient 属性?
【发布时间】:2018-10-11 07:41:01
【问题描述】:

EmployeeInfo 实体类

@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;

......

}

另一个实体类 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;
        }
    }

}

我试图通过 fkCommentedBy 属性在 getCommentedEmployee() 方法中找到一个 EmployeeInfo 对象,并将其设置为 @Transient 属性 commentedEmployee。

我发现了以下错误:

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"])

我该如何解决?

【问题讨论】:

  • 看起来您正在尝试在实体类中自动连接一个 spring bean - 因为实体实例不是一个 spring 托管 bean,所以它不起作用。如果您注意到异常消息 - 您会看到一个 NPE,我认为它是由 Null employeeInfoService 引起的。
  • 找到对象并对其进行测试,但无法设置为@Transient 属性变量
  • 非常感谢,我根据您的信息解决了。

标签: java spring-boot spring-data-jpa fasterxml jackson-databind


【解决方案1】:

@Transient 的目的是为非持久性属性建模,所以我不清楚当你通过“fkCommentedBy”属性持久化时,为什么要在 commentedByEmployee 属性上使用 @Transient。 IMO,@ManyToOne 在这种情况下更合适。

@Entity
@Table(name = "projecttaskcomments")
public class ProjectTaskComments {

// .... other declarations 
@ManyToOne
@JoinColumn(name="fkCommentedBy")
private EmployeeInfo commentedEmployee;
// ..... other code
}

现在如果你仍然想使用@Transient,那么在getter 方法中你需要确保你有一个对EmployeeInfoService 对象的有效引用。 @Autowired 在这里不起作用,因为 ProjectTaskComments 不是 Spring 托管的 bean。

【讨论】:

  • 非常感谢。我已经从你的信息中解决了
【解决方案2】:

同意@KishoreKirdat,需要检查 null 并进行一些初始化:

public EmployeeInfo getCommentedEmployee() {
  // check here
  if (employeeInfoService == null) return null;

  EmployeeInfo employeeInfo = employeeInfoService.getSingle...;
  if (employeeInfo != null) {
    // init here
    commentedEmployee = new EmployeeInfo();

    commentedEmployee.set...;
    return commentedEmployee;
  } else {
    return null;
  }
}

private void setCommentedEmployee(EmployeeInfo employeeInfo) {
  // do nothing
}

【讨论】:

  • 还需要检查 null 并按照@KishoreKirdat 建议进行一些初始化
【解决方案3】:

是的,我终于可以解决它了。我刚刚做了以下工作:

  1. 在 ProjectTaskComments 类中添加了@Component:

    @Entity    
    @Component    
    @Table(name = "projecttaskcomments")    
    public class ProjectTaskComments{
    ........
    
  2. 将 EmployeeInfoService 声明为静态,并为该服务添加了一个 seter 方法并@Autowired。

    @Transient
    private static EmployeeInfoService employeeInfoService;
    
    @Autowired
    public void setEmployeeInfoService(EmployeeInfoService employeeInfoService) {
        this.employeeInfoService = employeeInfoService;
    }
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-25
    • 1970-01-01
    • 2018-11-16
    • 1970-01-01
    • 2011-10-03
    • 2018-02-10
    • 2012-11-15
    • 1970-01-01
    相关资源
    最近更新 更多