Поиск поля первичного ключа для объекта Hibernate - PullRequest
4 голосов
/ 21 марта 2012

Можем ли мы программно найти поля первичного ключа для объекта Hibernate (аналогично JPA PersistenceUnitUtil)?

Ответы [ 3 ]

8 голосов
/ 21 марта 2012

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 (объектный объект, сеанс SessionImplementor)

Например: Предположим, у вас есть экземпляр управляемого объекта, загруженный из сеанса:

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) );
}
3 голосов
/ 05 июня 2014

Я понимаю, что этому вопросу уже более двух лет, и на него уже дан ответ, но он находится между первыми 10 результатами, которые Google находит для "hibernate get primarykeykey" (и, возможно, других подобных запросов), поэтому я думаю, что важно добавить эту информацию здесь.

Недавно я работал над системой Java, и мне нужно было получить первичный ключ (и) таблицы, однако все, что у меня было, - это объект Hibernate Configuration и имя таблицы.

Хотя ответ Йоханны очень прост и помог мне, я обнаружил, что он не работает должным образом для таблиц с составным первичным ключом, поскольку найдено только одно из полей, составляющих первичный ключ.

Я вскопал в свойствах 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, поэтому может быть лучшим и более кратким способом справиться с этим (я надеюсь, по крайней мере), но я могу ' не могу найти его.

3 голосов
/ 21 марта 2012

Взгляните на PersistentClass (вы получите это с configuration.getClassMapping(<classname>)). Там getIdentifierProperty() или getKeyClosureIterator() могут быть полезны - в зависимости от ваших потребностей.

...