Frage

Gibt es eine Möglichkeit, die EntityManager ohne Persistenzeinheit definiert zu initialisieren? Können Sie alle die erforderlichen Eigenschaften geben einen Entity Manager zu schaffen? Ich brauche die EntityManager aus Anwender angegebenen Werte zur Laufzeit erstellen. die persistence.xml und Neukompilieren Aktualisierung ist keine Option.

Jede Idee, wie dies zu tun ist mehr als willkommen!

War es hilfreich?

Lösung

  

Gibt es eine Möglichkeit, die EntityManager ohne Persistenzeinheit definiert zu initialisieren?

Sie sollten definieren mindestens ein Persistenzeinheit im persistence.xml Deployment Descriptor.

  

Können Sie alle erforderlichen Eigenschaften geben einen Entitymanager zu erstellen?

  • Das Attribut name ist erforderlich. Die anderen Attribute und Elemente sind optional. (JPA-Spezifikation). So sollte dies mehr oder weniger Ihre minimale persistence.xml-Datei:
<persistence>
    <persistence-unit name="[REQUIRED_PERSISTENCE_UNIT_NAME_GOES_HERE]">
        SOME_PROPERTIES
    </persistence-unit>
</persistence>
  

In Java EE-Umgebungen, die jta-data-source und non-jta-data-source Elemente angeben, werden verwendet, um die globalen JNDI Namen des JTA und / oder nicht-JTA Datenquelle durch die Persistenz-Provider verwendet werden.

Also, wenn Ihr Ziel Application Server unterstützt JTA (JBoss, Websphere, Glassfish), Ihre persistence.xml sieht aus wie:

<persistence>
    <persistence-unit name="[REQUIRED_PERSISTENCE_UNIT_NAME_GOES_HERE]">
        <!--GLOBAL_JNDI_GOES_HERE-->
        <jta-data-source>jdbc/myDS</jta-data-source>
    </persistence-unit>
</persistence>

Wenn Ihr Ziel Application Server unterstützt keine JTA (Tomcat), Ihr persistence.xml sieht aus wie:

<persistence>
    <persistence-unit name="[REQUIRED_PERSISTENCE_UNIT_NAME_GOES_HERE]">
        <!--GLOBAL_JNDI_GOES_HERE-->
        <non-jta-data-source>jdbc/myDS</non-jta-data-source>
    </persistence-unit>
</persistence>

Wenn Ihre Datenquelle ist nicht auf einen globalen JNDI gebunden (zB außerhalb eines Java EE-Container), so würden Sie in der Regel JPA-Provider definieren, Treiber, URL, Benutzer und Passwort Eigenschaften. Aber Eigenschaftsname ist abhängig von den JPA-Provider. Also, für Hibernate als JPA-Provider, Ihre persistence.xml Datei wird aussieht wie:

<persistence>
    <persistence-unit name="[REQUIRED_PERSISTENCE_UNIT_NAME_GOES_HERE]">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>br.com.persistence.SomeClass</class>
        <properties>
            <property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.ClientDriver"/>
            <property name="hibernate.connection.url" value="jdbc:derby://localhost:1527/EmpServDB;create=true"/>
            <property name="hibernate.connection.username" value="APP"/>
            <property name="hibernate.connection.password" value="APP"/>
        </properties>
    </persistence-unit>
</persistence>

Transaktionsart Attribut

  

In der Regel in Java EE-Umgebungen, eine transaktions Art von RESOURCE_LOCAL geht davon aus, dass eine nicht-JTA-Datenquelle zur Verfügung gestellt wird. In einer Umgebung mit Java EE, wenn dieses Element nicht angegeben ist, ist die Standard-JTA. In einer Umgebung mit Java SE, wenn dieses Element nicht angegeben ist, kann ein Ausfall von RESOURCE_LOCAL übernommen werden.

  • Um die Portabilität einer Java SE-Anwendung zu gewährleisten, ist es notwendig, explizit Liste die Persistenz Klassen verwaltet, die in der Persistenzeinheit (JPA-Spezifikation)
  • enthalten sind
  

Ich brauche die EntityManager aus Anwender angegebenen Werte zur Laufzeit erstellen

diese So verwenden:

Map addedOrOverridenProperties = new HashMap();

// Let's suppose we are using Hibernate as JPA provider
addedOrOverridenProperties.put("hibernate.show_sql", true);

Persistence.createEntityManagerFactory(<PERSISTENCE_UNIT_NAME_GOES_HERE>, addedOrOverridenProperties);

Andere Tipps

Ja, Sie können ohne eine XML-Datei zu verwenden, wie dies in einer @Configuration Klasse mit Feder (oder dessen Äquivalent Feder Config xml):

@Bean
public LocalContainerEntityManagerFactoryBean emf(){
    properties.put("javax.persistence.jdbc.driver", dbDriverClassName);
    properties.put("javax.persistence.jdbc.url", dbConnectionURL);
    properties.put("javax.persistence.jdbc.user", dbUser); //if needed

    LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
    emf.setPersistenceProviderClass(org.eclipse.persistence.jpa.PersistenceProvider.class); //If your using eclipse or change it to whatever you're using
    emf.setPackagesToScan("com.yourpkg"); //The packages to search for Entities, line required to avoid looking into the persistence.xml
    emf.setPersistenceUnitName(SysConstants.SysConfigPU);
    emf.setJpaPropertyMap(properties);
    emf.setLoadTimeWeaver(new ReflectiveLoadTimeWeaver()); //required unless you know what your doing
    return emf;
}

Ich konnte einen EntityManager mit Hibernate und PostgreSQL rein mit Hilfe von Java-Code (mit einer Spring-Konfiguration) den folgenden erstellen:

@Bean
public DataSource dataSource() {
    final PGSimpleDataSource dataSource = new PGSimpleDataSource();

    dataSource.setDatabaseName( "mytestdb" );
    dataSource.setUser( "myuser" );
    dataSource.setPassword("mypass");

    return dataSource;
}

@Bean
public Properties hibernateProperties(){
    final Properties properties = new Properties();

    properties.put( "hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect" );
    properties.put( "hibernate.connection.driver_class", "org.postgresql.Driver" );
    properties.put( "hibernate.hbm2ddl.auto", "create-drop" );

    return properties;
}

@Bean
public EntityManagerFactory entityManagerFactory( DataSource dataSource, Properties hibernateProperties ){
    final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource( dataSource );
    em.setPackagesToScan( "net.initech.domain" );
    em.setJpaVendorAdapter( new HibernateJpaVendorAdapter() );
    em.setJpaProperties( hibernateProperties );
    em.setPersistenceUnitName( "mytestdomain" );
    em.setPersistenceProviderClass(HibernatePersistenceProvider.class);
    em.afterPropertiesSet();

    return em.getObject();
}

Der Aufruf von LocalContainerEntityManagerFactoryBean.afterPropertiesSet() ist wesentlich , da sonst die Fabrik nie gebaut wird, und dann getObject() kehrt null und Sie jagen nach NullPointerExceptions den ganzen Tag lang. >: - (

Es dann mit dem folgenden Code gearbeitet:

PageEntry pe = new PageEntry();
pe.setLinkName( "Google" );
pe.setLinkDestination( new URL( "http://www.google.com" ) );

EntityTransaction entTrans = entityManager.getTransaction();
entTrans.begin();
entityManager.persist( pe );
entTrans.commit();

Wo meine Einheit wurde diese:

@Entity
@Table(name = "page_entries")
public class PageEntry {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    private String linkName;
    private URL linkDestination;

    // gets & setters omitted
}

Hier ist eine Lösung ohne Frühling. Konstanten werden von org.hibernate.cfg.AvailableSettings genommen:

entityManagerFactory = new HibernatePersistenceProvider().createContainerEntityManagerFactory(
            archiverPersistenceUnitInfo(),
            ImmutableMap.<String, Object>builder()
                    .put(JPA_JDBC_DRIVER, JDBC_DRIVER)
                    .put(JPA_JDBC_URL, JDBC_URL)
                    .put(DIALECT, Oracle12cDialect.class)
                    .put(HBM2DDL_AUTO, CREATE)
                    .put(SHOW_SQL, false)
                    .put(QUERY_STARTUP_CHECKING, false)
                    .put(GENERATE_STATISTICS, false)
                    .put(USE_REFLECTION_OPTIMIZER, false)
                    .put(USE_SECOND_LEVEL_CACHE, false)
                    .put(USE_QUERY_CACHE, false)
                    .put(USE_STRUCTURED_CACHE, false)
                    .put(STATEMENT_BATCH_SIZE, 20)
                    .build());

entityManager = entityManagerFactory.createEntityManager();

Und die berüchtigten PersistenceUnitInfo

private static PersistenceUnitInfo archiverPersistenceUnitInfo() {
    return new PersistenceUnitInfo() {
        @Override
        public String getPersistenceUnitName() {
            return "ApplicationPersistenceUnit";
        }

        @Override
        public String getPersistenceProviderClassName() {
            return "org.hibernate.jpa.HibernatePersistenceProvider";
        }

        @Override
        public PersistenceUnitTransactionType getTransactionType() {
            return PersistenceUnitTransactionType.RESOURCE_LOCAL;
        }

        @Override
        public DataSource getJtaDataSource() {
            return null;
        }

        @Override
        public DataSource getNonJtaDataSource() {
            return null;
        }

        @Override
        public List<String> getMappingFileNames() {
            return Collections.emptyList();
        }

        @Override
        public List<URL> getJarFileUrls() {
            try {
                return Collections.list(this.getClass()
                                            .getClassLoader()
                                            .getResources(""));
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        @Override
        public URL getPersistenceUnitRootUrl() {
            return null;
        }

        @Override
        public List<String> getManagedClassNames() {
            return Collections.emptyList();
        }

        @Override
        public boolean excludeUnlistedClasses() {
            return false;
        }

        @Override
        public SharedCacheMode getSharedCacheMode() {
            return null;
        }

        @Override
        public ValidationMode getValidationMode() {
            return null;
        }

        @Override
        public Properties getProperties() {
            return new Properties();
        }

        @Override
        public String getPersistenceXMLSchemaVersion() {
            return null;
        }

        @Override
        public ClassLoader getClassLoader() {
            return null;
        }

        @Override
        public void addTransformer(ClassTransformer transformer) {

        }

        @Override
        public ClassLoader getNewTempClassLoader() {
            return null;
        }
    };
}

Mit Klar JPA, unter der Annahme, dass Sie eine PersistenceProvider Implementierung (zB Hibernate), können Sie verwenden, um die PersistenceProvider # createContainerEntityManagerFactory (PersistenceUnitInfo Info, Karte map) Methode eine EntityManagerFactory Bootstrap ohne zu benötigen persistence.xml.

Allerdings ist es ärgerlich, dass Sie die PersistenceUnitInfo Schnittstelle zu implementieren, so dass Sie besser dran mit Spring oder Hibernate, die sowohl Unterstützung Bootstrapping JPA ohne persistence.xml-Datei:

this.nativeEntityManagerFactory = provider.createContainerEntityManagerFactory(
    this.persistenceUnitInfo, 
    getJpaPropertyMap()
);

Wenn die PersistenceUnitInfo implementiert durch die Federspezifische Klasse.

Schauen Sie sich diesem Artikel für ein schönes Beispiel dafür, wie Sie dieses Ziel mit Hibernate erreichen können.

Datanucleus JPA, dass ich auch eine Art und Weise, dies zu tun? in seiner docs . Keine Notwendigkeit für Frühling, oder hässliche Umsetzung PersistenceUnitInfo.

Einfach Sie folgt als

import org.datanucleus.metadata.PersistenceUnitMetaData;
import org.datanucleus.api.jpa.JPAEntityManagerFactory;

PersistenceUnitMetaData pumd = new PersistenceUnitMetaData("dynamic-unit", "RESOURCE_LOCAL", null);
pumd.addClassName("mydomain.test.A");
pumd.setExcludeUnlistedClasses();
pumd.addProperty("javax.persistence.jdbc.url", "jdbc:h2:mem:nucleus");
pumd.addProperty("javax.persistence.jdbc.user", "sa");
pumd.addProperty("javax.persistence.jdbc.password", "");
pumd.addProperty("datanucleus.schema.autoCreateAll", "true");

EntityManagerFactory emf = new JPAEntityManagerFactory(pumd, null);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top