查找Hibernate实体的主键字段

时间:2012-03-21 07:00:19

标签: hibernate primary-key

我们是否有可能以编程方式找到Hibernate实体的主键字段(类似于JPA的PersistenceUnitUtil)?

3 个答案:

答案 0 :(得分:8)

SessionFactory提供了一个名为getClassMetadata()的方法来获取类的元数据对象(即ClassMetadata

要获取实体的标识符属性的名称,请使用ClassMetadata.getIdentifierPropertyName()

ClassMetadata employeeMeta =  sessionFactory.getClassMetadata(Employee.class);
System.out.println("Name of the identifier property of the employee entity :" + employeeMeta .getIdentifierPropertyName());

要获取托管实体实例的标识符属性的值,请使用ClassMetadata.getIdentifier(Object entity, SessionImplementor session)

例如: 假设您有一个从会话加载的托管实体实例:

List<Employee> employeeList = (List<Employee>)session.createQuery("from Employee where gender ='F'").list();
ClassMetadata employeeMeta = session.getSessionFactory().getClassMetadata(Employee.class);
for (Employee employee : employeeList ) {
    System.out.println("Value of the Primary key:" + employeeMeta.getIdentifier(employee , session) );
}

答案 1 :(得分:3)

查看PersistentClass(您可以使用configuration.getClassMapping(<classname>)获得)。根据您的需要,getIdentifierProperty()getKeyClosureIterator()可能会有用。

答案 2 :(得分:3)

我意识到这个问题现在已经有两年多的时间了,已经回答了,但它介于Google发现的“hibernate获取主键字段”(可能还有其他类似查询)的前10个结果之间,所以我认为添加这些信息非常重要这里。

最近,我正在研究Java系统,我需要获取表的主键,但是,我所拥有的只是Hibernate Configuration对象和表的名称。

虽然Johanna的回答非常简单并且帮助了我,但我发现它对于具有复合主键的表没有预期效果,因为只找到组成主键的一个字段。

我挖掘了PersistentClass属性并找到了处理主键(复合和单一)两种情况的方法:

/**
 * Maps a table's primary key to a Map<String, String> where the keys are the names of
 * the fields that compose the primary key and the values are the type names of said
 * fields.
 * 
 * @param tableName The name of the which for which the primary keys will be gotten
 * @param hibernateConfiguration The Hibernate configuration for the database
 *     IMPORTANT: $tableName must be already mapped in the configuration.
 * @returns A map with the fields names as keys and their types' names as values.
 */
public static Map<String, String> retrievePrimaryKeys(String tableName, Configuration hibernateConfiguration) {
    hibernateConfiguration.buildMappings();

    HashMap<String, String> primaryKeys = new HashMap<>();
    PersistentClass tableMapping = hibernateConfiguration.getClassMapping(tableName);

    Object tableIdentifier =  tableMapping.getIdentifier();

    if(tableIdentifier instanceof SimpleValue) {

        // Whenever the identifier is a SimpleValue, it means that the table has only one PrimaryKey. 
        // At this point, it's assumed that the primary key was mapped using the <id> element in the mapping XML file.
        // We iterate over the columns below, because it's a safer way of handling this thing.

        SimpleValue tableIdentifierValue = (SimpleValue) tableIdentifier;
        Iterator primaryKeysIterator = tableIdentifierValue.getColumnIterator();

        while(primaryKeysIterator.hasNext()) {
            Column primaryKey = (Column) primaryKeysIterator.next();
            SimpleValue primaryKeyValue = (SimpleValue) primaryKey.getValue();
            primaryKeys.put(primaryKey.getName(), primaryKeyValue.getTypeName());
        }
    }
    else if (tableIdentifier instanceof Component)
    {
        // Whenever the identifier is a Component, it means that the table has a composite primary key.
        // At this point, it's assumed that the primary key was mapped using the <composite-id> element in the mapping XML file

        Component identifiers = (Component) tableIdentifier;
        Iterator identifierIterator = identifiers.getPropertyIterator();

        while(identifierIterator.hasNext()) {
            Property identifier = (Property) identifierIterator.next();
            SimpleValue value = (SimpleValue) identifier.getValue();

            primaryKeys.put(identifier.getName(), value.getTypeName());
        }
    }
    else
    {
        // If the program reaches this point, it means that Hibernate hates you and there's a third unknown way of declaring and getting a table's primary key.
    }

    return primaryKeys;
}

我必须补充一点,Java不是我的专长,因为Hibernate都不是,所以可能是一种更好,更简洁的处理方式(我希望至少如此),但我可以找不到。