Ответы пользователя по тегу Java
  • Как JPA понимает, какую реализацию использовать?

    shebbs
    @shebbs Автор вопроса
    В общем ответ такой:
    JPA - это не просто какая-то абстрактная спецификация, там есть вполне конкретные классы, выполняющие конкретные действия. В частности:
    import javax.persistence.Persistence;
    EntityManagerFactory factory = Persistence.createEntityManagerFactory("dvdPU");

    В классе Persistence метод createEntityManagerFactory выполняет вполне конкретные действия (можно посмотреть исходники тут https://github.com/javaee/jpa-spec/blob/master/jav...), а именно:
    1. Сначала находит в classpath все возможные классы, которые могут создать EntityManagerFactory.
    2. Потом перебирает все, которые нашел, по очереди, каждый раз передавая очередному "создателю" конфиг из persistence.xml.
    3. Как только "создатель" создает фабрику, цикл прекращается и фабрика возвращается в нашу программу.

    Если мы не указываем в persistence.xml через тег provider конкретного провайдера, тогда фабрику нам создаст первый попавшийся провайдер. Если же указываем, тогда фабрику нам создаст именно тот, который мы хотим. Пусть Persistence нашел в classpath два провайдера в таком порядке: EclipseLink и Hibernate. Он сперва просит EclipseLink создать фабрику и передает ему конфиг. EclipseLink видит, что в конфиге написано "Hibernate" и отвечает: "Извини, братишка, не в этот раз, в конфиге написано, что это хибер должен делать. Так что я не буду". Тогда Persistence идет дальше по списку, просит хибер и передает ему конфиг. Хибер видит, что в provider стоит org.hibernate.jpa.HibernatePersistenceProvider и создает фабрику.

    Вот так у нас и оказывается КОНКРЕТНАЯ, хиберовская, реализация фабрики, из которой мы уже дальше получаем такие же конкретные, хиберовские, реализации EntityManager и прочее.

    Ну а в classpath все эти провайдеры попадают за счет того, что у нас в pom есть зависимости.
    Ответ написан
    Комментировать