我所有的 JPA 实体类都实现了一个名为 Entity 的接口(interface),其定义如下:
public interface Entity extends Serializable {
// some methods
}
我的 JPA 实体的某些字段顶部有 @Column
注释,有些则没有。 MyEntity
类定义如下:
@Entity
public class MyEntity implements Entity {
@Id
private Long id; // Assume that it is auto-generated using a sequence.
@Column(name="field1")
private String field1;
private SecureString field2; //SecureString is a custom class
//getters and setters
}
我的删除方法接受一个实体。
@Override
public void delete(Entity baseEntity) {
em.remove(baseEntity); //em is entityManager
}
每当调用 delete 方法时,我都希望在 delete 方法中包含三样东西:
1) MyEntity
的 SecureString
类型的字段
2) 数据库中该特定字段的列名(该字段可能有也可能没有 @Column
注释)
3)id
字段的值
注意当delete()
方法被调用时,我们并不知道它是针对哪个实体调用的,可能是针对MyEntity1
、MyEntity2
等
我试过做如下的事情:
for (Field field : baseEntity.getClass().getFields()) {
if (SecureString.class.isAssignableFrom(field.getType())) {
// But the field doesn't have annotation @Column specified
Column column = field.getAnnotation(Column.class);
String columnName = column.name();
}
}
但这仅在该字段具有 @Column
注释时才有效。它也没有给我其他两件我需要的东西。有什么想法吗?
最佳答案
Hibernate 可以使用不同的naming strategies映射隐式定义的属性名称(没有 @Column(name = "..."))。要获得“物理”名称,您需要深入了解 Hibernate 的内部结构。首先,您必须将 EntityManagerFactory
连接到您的服务。
@Autowired
private EntityManagerFactory entityManagerFactory;
其次,您必须为您的类检索一个AbstractEntityPersister
SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
AbstractEntityPersister persister = ((AbstractEntityPersister)sessionFactory.getClassMetadata(baseEntity.getClass()));
第三,您的代码就快完成了。您只需要处理这两种情况 - 使用和不使用 @Column 注释。试试这个:
for (Field field : baseEntity.getClass().getFields()) {
if (SecureString.class.isAssignableFrom(field.getType())) {
String columnName;
if (field.isAnnotationPresent(Column.class)) {
columnName = field.getAnnotation(Column.class).name();
} else {
String[] columnNames = persister.getPropertyColumnNames(field.getName());
if (columnNames.length > 0) {
columnName = columnNames[0];
}
}
}
}
请注意,getPropertyColumnNames()
仅检索不属于主键的“属性”字段。要检索键列名称,请使用 getKeyColumnNames()
。
关于 id
字段。您真的需要在子类中拥有所有@Id 吗?也许最好将@Id 移动到Entity
类并用@MappedSuperclass 注释标记这个类?然后您可以使用 baseEntity.getId();
关于java - 如何获取 JPA 实体的列名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46335682/