WrongClassException:Object [id = null]不是指定的子类

时间:2017-05-08 13:16:45

标签: java hibernate jpa

我有一个如下所示的模型:

@Entity(name = "request")
public class VisitRequest {
  @Id
  @GeneratedValue
  private Long id;

  @OneToMany(mappedBy = "visitRequest", cascade = CascadeType.ALL, orphanRemoval = true)
  @JsonManagedReference
  private List<Visitor> visitors;

  //default constructor, getters and setters
}

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "class")
public class Visitor {
  @Id
  @GeneratedValue
  private Long id;

  @ManyToOne
  @JsonBackReference
  private VisitRequest visitRequest;

  //default constructor, getters and setters

}

@Entity
public class ContactPerson extends Visitor {

  private PhoneNumber phoneNumber;

  //default constructor, getters and setters

}

但是当我尝试通过与联系人交换其中一个访问者来更新visitRequest时,尝试在CRUD存储库上执行该方法visitRequestRepository.save(visitRequest);我得到了这个例外:

  

用于servlet [dispatcherServlet]的Servlet.service()与path的上下文   []引发异常[请求处理失败;嵌套异常是   org.springframework.orm.ObjectRetrievalFailureException:Object   [id = null]不是指定的子类   [cern.ais.visits.core.domain.visitor.Visitor]:给定的类   对象与持久副本的类不匹配;嵌套异常是   org.hibernate.WrongClassException:Object [id = null]不是   指定的子类[cern.ais.visits.core.domain.visitor.Visitor]:   给定对象的类与持久化副本的类不匹配   根本原因

问题可能是数据库中有一个在contact_person和visitor表中使用的相同的id?

我该如何解决这个问题?我已经搜索了解决方案,但没有一个能为我工作。

3 个答案:

答案 0 :(得分:0)

您可能没有初始化visitRequest中的ContactPerson参考。请看一下以下配置,它与Spring Boot JPA一起使用。我已经使用lombok来生成GetterSetters

这是在Spring Boot https://github.com/ConsciousObserver/SpringBootJpaInheritance

中实现的工作示例
@Data
@Entity(name = "request")
class VisitRequest {
    @Id
    @GeneratedValue
    private Long id;

    @OneToMany(mappedBy = "visitRequest", cascade = CascadeType.ALL, orphanRemoval = true)
    @JsonManagedReference
    private List<Visitor> visitors = new ArrayList<>();
}

@NoArgsConstructor
@Data
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "class")
class Visitor {
    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne
    @JsonBackReference
    private VisitRequest visitRequest;

    public Visitor(VisitRequest visitRequest) {
        this.visitRequest = visitRequest;
    }
}

@NoArgsConstructor
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@Entity
class ContactPerson extends Visitor {
    private String phoneNumber;

    public ContactPerson(VisitRequest visitRequest, String phoneNumber) {
        super(visitRequest);
        this.phoneNumber = phoneNumber;
    }
}

答案 1 :(得分:0)

我怀疑您遇到此问题的原因是注释private List<MasterPageItem> listOfItems = new List<MasterPageItem>(); MasterPageItem pages = new MasterPageItem(); public SlideMenu() { InitializeComponent(); test.BindingContext = getPages(); } public List<MasterPageItem> getPages() { listOfItems.Add(new MasterPageItem("TEST1", typeof(Test1))); listOfItems.Add(new MasterPageItem("TEST2", typeof(Test2))); return listOfItems; } 没有被继承。如果您在ContactPerson中定义属性ID,则将生成一个ID,并且不再是问题。

尝试将ContactPerson类更改为:

public class MasterPageItem
{
    public string Title { get; set; }
    public Type TargetType { get; set; }

    public MasterPageItem()
    {
    }
    public MasterPageItem(string Title, Type TargetType)
    {
        this.Title = Title;
        this.TargetType = TargetType;
    }
}

答案 2 :(得分:0)

@Entity(name = "request")
public class VisitRequest {
  @Id
  @GeneratedValue
  private Long id;

  @OneToMany(mappedBy = "visitRequest", cascade = CascadeType.ALL, orphanRemoval = true)
  @JsonManagedReference
  private List<Visitor> visitors;

  //default constructor, getters and setters
}

@Entity(name = "visitor")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "visitor_type", discriminatorType = DiscriminatorType.STRING, length = 16)
@DiscriminatorValue(value = "visitor")
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "class")
public class Visitor {
  @Id
  @GeneratedValue
  private Long id;

  @ManyToOne
  @JsonBackReference
  private VisitRequest visitRequest;

  //default constructor, getters and setters

}

@Entity(name = "contact_person")
@Table(name = "contact_person")
@DiscriminatorValue(value = "contact_person")
public class ContactPerson extends Visitor {

  private PhoneNumber phoneNumber;

  //default constructor, getters and setters

}

您就可以像ContactPersonDao.save(contactPerson)这样保留ContactPerson, 您无法通过访问者链接保留字段。 我不是专家,但对我有用。 如果访客不与人联系,您可以将访客坚持为访客