使用 findAll() 方法时如何避免休眠创建抽象类的对象?

Posted

技术标签:

【中文标题】使用 findAll() 方法时如何避免休眠创建抽象类的对象?【英文标题】:How to avoid hibernate from creating object of abstract class when using findAll() method? 【发布时间】:2022-01-19 22:12:05 【问题描述】:

我有抽象类 Employee 和 3 个从雇员扩展的具体类。 从Employee 扩展的类,例如OfficeEmployee 目前是空的,也代表数据库中的表。这些具体类的唯一目的是让 fk 引用Employee。例如,如果OfficeEmployee被创建,则Employee实体中会保存一个数据,OfficeEmployee实体中只会保存一个id。

这是我的 Employee 类:

@Entity
@Data
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Employee 
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "employee_id", nullable = false, unique = true)
private int employeeId;

@Column(name = "employee_name", nullable = false)
private String name;

@Column(name = "reason_for_deactivation", length = 255)
private String reasonForDeactivation = "";

@Column(name = "deleted", nullable = false)
private Boolean isDeleted = Boolean.FALSE;

我已经设法编写了用于保存、更新和删除特定员工的方法,但是当我想获取所有员工时,我不能这样做,因为后台休眠正在尝试从 Employee 类创建对象并且我得到错误,因为类是抽象的。

这是获取所有员工的方法:

@Service
public class EmployeeServiceImpl 

@Autowired
private EmployeeRepository employeeRepository;

  public List<Employee> findAll() 
    return employeeRepository.findAll();

 

我该如何解决这个问题?我愿意接受任何建议,包括改变我的架构。

【问题讨论】:

你有@DiscriminatorColumn 吗?您需要这样才能使 hibernate 实例化正确的子类。 我假设你还没有找到***.com/questions/25237664/…,请阅读它,看看它是否回答了你的问题 @MartinFrey 我试图避免在 Employee 中添加新列,但此时我别无选择。不过还是谢谢 如果只是引用具有办公室的员工,以及其他没有附加属性的引用,您可以将员工设为具体类并使用多对多属性。 【参考方案1】:

最简单的解决方案是在Employee 实体上添加@DiscriminatorColumn,在具体类上添加@DiscriminatorValue。所以现在看起来像这样:

@Entity
@DiscriminatorColumn(name = "employee_type") // This is added
@Data
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Employee 
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "employee_id", nullable = false, unique = true)
private int employeeId;

@Column(name = "employee_name", nullable = false)
private String name;

@Column(name = "reason_for_deactivation", length = 255)
private String reasonForDeactivation = "";

@Column(name = "deleted", nullable = false)
private Boolean isDeleted = Boolean.FALSE;

具体类:

@Entity
@Data
@DiscriminatorValue("Office_Employee")  // This is added
public class OfficeEmployee extends Employee


基本上,它将在名为employee_type 的Employee 实体中添加新列,并基于该列包含每个员工的类型信息,因此我现在可以获取所有员工。

【讨论】:

以上是关于使用 findAll() 方法时如何避免休眠创建抽象类的对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何避免 FindAll 条件默认设置为“未定义”

QueryDsl SpringData Jpa findAll 如何避免count()

如何避免警告“使用集合提取指定的 firstResult/maxResults;在内存中应用!”啥时候使用休眠?

替换Groovy XML节点会导致后续findAll调用出现问题

如何在此方法中避免 LazyInitializationException?

使用对象作为主要条件时如何在选择之间使用 SpringData findAll()?