我的所有JPA实体类都实现了一个名为Entity的接口,它的定义如下:
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)DB中该特定字段的列名(该字段可能有也可能没有@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,reflection,jpa,hibernate,java-ee
来源: https://codeday.me/bug/20190522/1153665.html