如何获取JPA实体的列名 [英] How to get Column names of JPA entity

查看:355
本文介绍了如何获取JPA实体的列名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我所有的JPA实体类都实现了一个称为Entity的接口,其定义如下:

All my JPA entity classes implement an interface called Entity which is defined like this:

public interface Entity extends Serializable {
// some methods

}

我的JPA实体的某些字段在其顶部具有@Column注释,而有些则没有. MyEntity类的定义如下:

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:

@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

}

我的delete方法接受一个实体.

My delete method accepts an Entity.

@Override
public void delete(Entity baseEntity) {

   em.remove(baseEntity); //em is entityManager
}

无论何时调用delete方法,我都希望在delete方法中包含三件事:

Whenever the delete method is invoked I want three things inside my delete method:

1)MyEntity类型为SecureString

2)DB中该特定字段的列名(该字段可能带有或不带有@Column批注)

2) Column name of that particular field in DB (The field may or may not have @Column annotation)

3)id字段的值

请注意,当调用delete()方法时,我们不知道为哪个实体调用,可能是MyEntity1MyEntity2等.

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.

我尝试做以下事情:

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批注的情况下有效.同样,这并没有给我带来我需要的其他两件事.有什么想法吗?

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?

推荐答案

Hibernate可以使用不同的EntityManagerFactory连接到服务.

Hibernate can use different naming strategies to 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.

@Autowired
private EntityManagerFactory entityManagerFactory;

第二,您必须为您的课程检索AbstractEntityPersister

Second, you have to retrieve an AbstractEntityPersister for your class

    SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
    AbstractEntityPersister persister = ((AbstractEntityPersister)sessionFactory.getClassMetadata(baseEntity.getClass()));

第三,您的代码几乎就在那里.您只需要处理两种情况-带和不带@Column注释.试试这个:

Third, you're almost there with your code. You just have to handle both cases - with and without @Column annotation. Try this:

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().

Note that getPropertyColumnNames() retrieves only 'property' fields, that are not a part of primary key. To retrieve key column names, use getKeyColumnNames().

关于id字段.您真的需要在子类中包含所有@Id吗?也许最好将@Id移到Entity类,并用@MappedSuperclass批注标记该类?然后,您可以使用baseEntity.getId();

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();

这篇关于如何获取JPA实体的列名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆