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 @Column
annotation on top of them and some don't. MyEntity
class 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 MyEntity
that are of type SecureString
1)MyEntity
属于类型的字段SecureString
2) Column name of that particular field in DB (The field may or may not have @Column
annotation)
2)DB中该特定字段的列名(该字段可能有也可能没有@Column
注释)
3) The value of id
field
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
, MyEntity2
etc.
请注意,当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 @Column
annotation. 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 EntityManagerFactory
to your service.
Hibernate 可以使用不同的命名策略来映射属性名称,这些名称是隐式定义的(没有@Column(name = "..."))。要获得“物理”名称,您需要深入了解 Hibernate 内部结构。首先,您必须将 an 连接EntityManagerFactory
到您的服务。
@Autowired
private EntityManagerFactory entityManagerFactory;
Second, you have to retrieve an AbstractEntityPersister
for 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 id
field. Do you really need to have all @Id's in child classes? Maybe would better to move @Id to Entity
class and mark this class with @MappedSuperclass annotation? Then you can retrieve it just with baseEntity.getId();
而关于id
领域。您真的需要在子类中拥有所有@Id 吗?也许最好将@Id 移动到Entity
类并用@MappedSuperclass 注释标记这个类?然后你可以用baseEntity.getId();