2010-09-24 2 views
3

Я знаю, что эта тема обсуждалась много раз, но по-прежнему требуются некоторые разъяснения по проблеме, с которой мы сталкиваемся. Hibernate best practices говорят об использовании натуральных ключей для методов equals/hashCode. У нас есть составной ключ, который состоит из 2 параметров (например, String name, Organization org), к которым принадлежит определенный объект. К сожалению, я не могу использовать org, поскольку он лениво загружен и приводит к другим проблемам, и я также не хочу создавать суррогатный ключ (возможно, автоматически созданный из базы данных или UUID, созданный с помощью вызова API до создания объекта). Какие параметры у меня есть, поскольку в указанных выше объектах (имя, org) поля уникальны, и я не могу просто написать свою логику только на основе самого поля имени. Является ли суррогатный ключ единственным вариантом, означает ли это, что я должен хранить это значение как часть каждой строки таблицы?Использование натуральных ключей как части равных и hashCode

ответ

2

Рекомендации по использованию Hibernate говорят об использовании натуральных ключей для методов equals/hashCode.

Да, поэтому я не буду подробно останавливаться на этом.

У нас есть составной ключ, который состоит из двух параметров (например, имя строки, организация org), к которому принадлежит определенный объект. К сожалению, я не могу использовать org, так как он лениво загружен и приводит к другим проблемам.

Не могли бы вы немного разобраться и проиллюстрировать каким-то кодом? Я хотел бы понять, как вы это сделали, и в чем проблема.

Какие варианты у меня есть с тех пор, как в указанных выше объектах (имя, org) поля уникальны, и я не могу просто написать свою логику только на основе самого поля имени.

Как я уже говорил, предоставление более подробной информации может помочь. Но на всякий случай обратите внимание, что вызов org.getId() на прокси не должен запускать загрузку объекта, если вы используете property access type, чтобы вы могли использовать его в своей реализации равным образом.

+0

Up для определения собственности которая позволяет пользователю получить идентификатор связанного объекта без попадания в базу данных –

0

Что называется названным объектом и организацией? Я предполагаю, что это называется Foo. Я так понимаю, вы не можете сказать foo.getOrganization(), потому что соединение с базой данных закрыто? Можете ли вы изменить свой FooDAO, чтобы он загружал Организацию, как только foo читается из базы данных?

Затем он будет доступен позже, когда вам нужно что-то сделать с помощью equals() и hashCode().

4

Если вы хотите что-то вроде

public class MyEntity { 

    private String name; 

    private Organization organization; 

    // getter's and setter's 

    public boolean equals(Object o) { 
     if(!(o instanceof MyEntity)) 
      return false; 

     MyEntity other = (MyEntity) o; 
     return new EqualsBuilder().append(getName(), other.getName()) 
            .append(getOrganization(), other.getOrganization()) 
            .isEquals(); 
    } 

} 

Но если вы хотите, чтобы избежать этого, потому что вы теперь хотите загрузить ленивый загруженный объект, вы можете рассчитывать на Hibernate.isInitialized методе и поставить свой обычай рутина

public boolean equals(Object o) { 
    if(!(o instanceof MyEntity)) 
     return false; 

    MyEntity other = (MyEntity) o; 
    boolean equals = new EqualsBuilder().append(getName(), other.getName()) 
             .isEquals(); 

    if(Hibernate.isInitialized(getOrganization())) { 
     // loaded Organization 
    } else { 
     // supply custom routine 
    } 

    return equals; 
} 

у меня есть не обновляемый веб-страницу, где Hibernate поставку следующей матрицы

         no eq/hC at all eq/hC with the id property eq/hC with buisness key 
use in a composite-id     No    Yes       Yes 
multiple new instances in set   Yes    No       Yes 
equal to same object from other session No    Yes       Yes 
collections intact after saving   Yes    No       Yes   

Где различные проблемы заключаются в следующем:

использование в составном-ID:

использовать объект в качестве составного-идентификатора, он должен осуществить равных/хэш-код в некотором роде == идентичности в этом случае будет недостаточно.

несколько новых экземпляров в комплекте:

Будет ли следующая работа или нет:

HashSet someSet = new HashSet(); 
someSet.add(new PersistentClass()); 
someSet.add(new PersistentClass()); 
assert(someSet.size() == 2); 

равным тому же объекту из другого сеанса:

Будет ли следующая работа или нет:

PersistentClass p1 = sessionOne.load(PersistentClass.class, new Integer(1)); 
PersistentClass p2 = sessionTwo.load(PersistentClass.class, new Integer(1)); 
assert(p1.equals(p2)); 

коллекции нетронутыми после сохранения:

Будет ли следующая работа или нет:

HashSet set = new HashSet(); 
User u = new User(); 
set.add(u); 
session.save(u); 
assert(set.contains(u)); 

Он также выделить этот Thread где равна реализации/Hashcode сильно обсуждается

+0

IMHO, проблема заключается в реализации hashCode ион. Интересно, как OP мог реализовать (согласованный) хэш-код с его ленивой загруженной Организацией. –

Смежные вопросы