java 如何获取 JPA 实体的列名
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/46335682/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get Column names of JPA entity
提问by Aman
All my JPA entity classes implement an interface called Entity which is defined like this:
我所有的 JPA 实体类都实现了一个名为 Entity 的接口,其定义如下:
public interface Entity extends Serializable {
// some methods
}
Some of the fields of my JPA entity have @Columnannotation on top of them and some don't. MyEntityclass is defined like below:
我的 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
}
My delete method accepts an Entity.
我的删除方法接受一个实体。
@Override
public void delete(Entity baseEntity) {
em.remove(baseEntity); //em is entityManager
}
Whenever the delete method is invoked I want three things inside my delete method:
每当调用 delete 方法时,我都希望在 delete 方法中包含三件事:
1) Fields of MyEntitythat are of type SecureString
1)MyEntity属于类型的字段SecureString
2) Column name of that particular field in DB (The field may or may not have @Columnannotation)
2)DB中该特定字段的列名(该字段可能有也可能没有@Column注释)
3) The value of idfield
3)id字段值
Note that when the delete()method is invoked, we don't know for which entity it is invoked, it may be for MyEntity1, MyEntity2etc.
请注意,当delete()方法被调用时,我们不知道哪个实体调用它,它可能是MyEntity1,MyEntity2等等。
I have tried doing something like below:
我试过做类似下面的事情:
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();
}
}
But this will only work if the field has @Columnannotation. Also it doesn't get me other two things that I need. Any ideas?
但这只有在该字段有@Column注释时才有效。它也没有让我得到我需要的其他两件事。有任何想法吗?
回答by Anatoly Shamov
Hibernate can use different naming strategiesto map property names, which are defined implicitly (without @Column(name = "...")). To have a 'physical' names you need to dive into Hibernate internals. First, you have to wire an EntityManagerFactoryto your service.
Hibernate 可以使用不同的命名策略来映射属性名称,这些名称是隐式定义的(没有@Column(name = "..."))。要获得“物理”名称,您需要深入了解 Hibernate 内部结构。首先,您必须将 an 连接EntityManagerFactory到您的服务。
@Autowired
private EntityManagerFactory entityManagerFactory;
Second, you have to retrieve an AbstractEntityPersisterfor your class
其次,你必须AbstractEntityPersister为你的班级检索一个
SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
AbstractEntityPersister persister = ((AbstractEntityPersister)sessionFactory.getClassMetadata(baseEntity.getClass()));
Third, you're almost there with your code. You just have to handle both cases - with and without @Column annotation. Try this:
第三,您的代码就快完成了。您只需要处理这两种情况 - 有和没有 @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];
}
}
}
}
Note that getPropertyColumnNames()retrieves only 'property' fields, that are not a part of primary key. To retrieve key column names, use getKeyColumnNames().
请注意,getPropertyColumnNames()仅检索不属于主键的“属性”字段。要检索键列名称,请使用getKeyColumnNames().
And about idfield. Do you really need to have all @Id's in child classes? Maybe would better to move @Id to Entityclass and mark this class with @MappedSuperclass annotation? Then you can retrieve it just with baseEntity.getId();
而关于id领域。您真的需要在子类中拥有所有@Id 吗?也许最好将@Id 移动到Entity类并用@MappedSuperclass 注释标记这个类?然后你可以用baseEntity.getId();

