Транзакции Hibernate и Spring - с использованием частных конструкторов / статических фабричных методов - PullRequest
2 голосов
/ 03 декабря 2008

У нас есть приложение Hibernate / Spring, которое имеет следующие компоненты Spring:

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" />

При соединении приложения мы получаем следующую ошибку при использовании частных конструкторов в наших спящих объектах:

Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: No visible constructors in class 'ourclass'

Объекты - это типичные доменные объекты, такие как Сотрудник или тому подобное.

При изменении модификатора видимости конструктора на пакет (или общедоступный) приложение работает нормально, а сущности сохраняются / загружаются в базу данных. Как мы / можем ли мы использовать частные конструкторы / статические фабричные методы с управлением транзакциями Spring / Hibernate?

Мы используем аннотации Hibernate для отображения сущностей / отношений. Не определены определения bean-компонентов в applicationContext.xml для класса домена, который связан с проблемой. Это ПОЖО, которое должно иметь статический метод фабрики и закрытый конструктор.

Как мы можем заставить Hibernate (классы org.springframework.spring-orm.hibernate3, я полагаю) использовать метод статической фабрики вместо конструктора? Или, если необходимо, сделать так, чтобы он вызывал приватный конструктор?

Использование весенней конфигурации фабричного метода имело бы смысл, но сущности не отображаются как бины в нашем applicationContext.xml. Они аннотируются только аннотацией @Entity для сохранения Hibernate.

Надеюсь, что это изменение прояснит (а не загадит) вопрос. :)

Ответы [ 4 ]

5 голосов
/ 07 декабря 2008

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

Вы можете сделать это через Interceptor, который является классом, который прослушивает несколько ключевых событий гибернации, например, когда объект должен быть создан или когда объект загружен.

Чтобы Hibernate использовал ваши собственные средства создания объекта, сделайте что-то вроде этого:

public class MyInterceptor extends EmptyInterceptor {

    public Object instantiate(String entityName, EntityMode entityMode, Serializable id) {
        if(entityName.equals(Foo.class.getName())
             return Foo.create();
        return null;
    }
}

Я немного удивлен, что у вас есть проблемы с Hibernate, когда не создаются экземпляры объектов с невидимым конструктором, учитывая, что это можно обойти с помощью отражения, и у меня не было этой проблемы в моем проекте (не из классов на самом деле есть видимые конструкторы). Это может быть что-то с весной. Проверьте, какую версию hibernate вы также используете.

1 голос
/ 03 декабря 2008

Знаете ли вы о свойстве "фабрика-метод"? Вы можете сделать так, чтобы Spring вызывал этот метод вместо конструктора для создания экземпляра bean-компонента.

0 голосов
/ 03 декабря 2008

В разделе 3.2.3.2 Spring Reference обсуждаются несколько различных способов создания экземпляров bean-компонентов в Spring.

Вам интересны статические методы фабрики или фабрики экземпляров. Все подразделы довольно короткие. Посмотрите, есть ли у вас дополнительные вопросы.

0 голосов
/ 03 декабря 2008

Я не думаю, что вы можете заставить Hibernate (или любую внешнюю среду) вызывать приватный конструктор для ваших объектов, если только это не какой-то подкласс, созданный во время выполнения javassist или cglib.

Если вы хотите, чтобы Hibernate вызывал ваш конструктор, почему бы вам просто не сделать его public или package? Hibernate создает ваши объекты, вызывая конструктор по умолчанию без аргументов. В документации говорится, что ваши классы должны иметь конструктор по умолчанию без аргументов с пакетом или публичной видимостью. Ваши классы не должны быть final, потому что Hibernate создает прокси для них при использовании ассоциаций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...