दृढ़ता के बिना JPA EntityManager बनाएँ। xml कॉन्फ़िगरेशन फ़ाइल


82

क्या EntityManagerएक दृढ़ता इकाई को परिभाषित किए बिना आरंभ करने का एक तरीका है ? क्या आप एक इकाई प्रबंधक बनाने के लिए सभी आवश्यक गुण दे सकते हैं? मुझे EntityManagerरनटाइम पर उपयोगकर्ता के निर्दिष्ट मूल्यों से बनाने की आवश्यकता है। persistence.xmlऔर पुनः अद्यतन करना कोई विकल्प नहीं है।

यह कैसे करना है पर कोई विचार स्वागत से अधिक है!

जवाबों:


57

क्या EntityManagerएक दृढ़ता इकाई को परिभाषित किए बिना आरंभ करने का एक तरीका है ?

आपको परिनियोजन वर्णनकर्ता में कम से कम एक दृढ़ता इकाई को परिभाषित करना चाहिए persistence.xml

आप एक बनाने के लिए सभी आवश्यक गुण दे सकते हैं Entitymanager?

  • नाम विशेषता की आवश्यकता है। अन्य विशेषताएँ और तत्व वैकल्पिक हैं। (जेपीए विनिर्देश)। तो यह कम से कम आपकी न्यूनतम persistence.xmlफ़ाइल होनी चाहिए :
<persistence>
    <persistence-unit name="[REQUIRED_PERSISTENCE_UNIT_NAME_GOES_HERE]">
        SOME_PROPERTIES
    </persistence-unit>
</persistence>

जावा ईई वातावरण में, jta-data-sourceऔर non-jta-data-sourceतत्वों का उपयोग JTA के वैश्विक JNDI नाम और / या गैर-JTA डेटा स्रोत को दृढ़ता प्रदाता द्वारा उपयोग किए जाने के लिए निर्दिष्ट करने के लिए किया जाता है।

इसलिए यदि आपका लक्ष्य एप्लिकेशन सर्वर JTA (JBoss, Websphere, GlassFish) का समर्थन करता है, तो आपका persistence.xmlऐसा दिखता है:

<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>

यदि आपका लक्ष्य एप्लिकेशन सर्वर JTA (Tomcat) का समर्थन नहीं करता है, तो आपका persistence.xmlऐसा दिखता है:

<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>

यदि आपका डेटा स्रोत किसी वैश्विक JNDI (उदाहरण के लिए, जावा EE कंटेनर के बाहर) के लिए बाध्य नहीं है, तो आप आमतौर पर JPA प्रदाता, ड्राइवर, url, उपयोगकर्ता और पासवर्ड गुणों को परिभाषित करेंगे। लेकिन संपत्ति का नाम जेपीए प्रदाता पर निर्भर करता है। तो, JPA प्रदाता के रूप में हाइबरनेट के लिए, आपकी persistence.xmlफ़ाइल निम्न प्रकार दिखाई देगी:

<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>

लेन-देन प्रकार विशेषता

सामान्य तौर पर, जावा ईई वातावरण में, एक लेनदेन-प्रकार RESOURCE_LOCALमानता है कि एक गैर-जेटीए डेटा स्रोत प्रदान किया जाएगा। एक जावा ईई वातावरण में, यदि यह तत्व निर्दिष्ट नहीं है, तो डिफ़ॉल्ट JTA है। एक जावा एसई वातावरण में, यदि यह तत्व निर्दिष्ट नहीं है, तो डिफ़ॉल्ट को RESOURCE_LOCALग्रहण किया जा सकता है।

  • जावा एसई एप्लिकेशन की पोर्टेबिलिटी का बीमा करने के लिए, दृढ़ता से प्रबंधित इकाई (जेपीए विनिर्देश) में शामिल किए गए प्रबंधित वर्गों को स्पष्ट रूप से सूचीबद्ध करना आवश्यक है।

मुझे EntityManagerरनटाइम पर उपयोगकर्ता के निर्दिष्ट मूल्यों से बनाने की आवश्यकता है

तो इस का उपयोग करें:

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);

नमस्ते, मैंने आपके समाधान की कोशिश की, लेकिन समस्याओं में चला गया, क्या आप मेरे प्रश्न की जांच कर सकते हैं: stackoverflow.com/questions/3935394/…
स्टेकर

लेकिन ... सवाल यह था कि दृढ़ता के बिना JPA EntityManager कैसे बनाया जाए । यह उत्तर अच्छा है, लेकिन यह अभी भी दृढ़ता का उपयोग कर रहा है। xml, है ना?
यहोशू डेविस

JavaEE एनवायरनमेंट में, एक EntityManagerFactory बनाते हुए उन्हें EJB / JPA द्वारा प्रबंधित किया जाता है?
एंथनी विनय

29

हाँ आप बिना किसी xml फ़ाइल का उपयोग किए बिना वसंत का उपयोग इस तरह कर सकते हैं जैसे @Configuration class (या इसके समतुल्य स्प्रिंग कॉन्फ़िग 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;
}

क्या वस्तु है properties?
थ्रोट

यह एक साधारण java.util.Properties वस्तु है
फ्रैंक ऑरेलाना

20

यहाँ वसंत के बिना एक समाधान है। से लिया जाता है org.hibernate.cfg.AvailableSettings:

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();

और बदनाम है 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;
        }
    };
}

3
इससे मुझे बहुत मदद मिली क्योंकि इसने मुझे कुछ परीक्षण मामलों में आर्किसिलियन का उपयोग करने के ओवरहेड से बचने में मदद की!
क्लर्क

18

मैं EntityManagerहाइबरनेट और PostgreSQL के साथ विशुद्ध रूप से जावा कोड (स्प्रिंग कॉन्फ़िगरेशन के साथ) का उपयोग करके निम्नलिखित बनाने में सक्षम था :

@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();
}

करने के लिए कॉल LocalContainerEntityManagerFactoryBean.afterPropertiesSet()है आवश्यक के बाद से अन्यथा कारखाने में निर्मित हो जाता है कभी नहीं, और फिर getObject()रिटर्न nullऔर आप के बाद का पीछा करते हुए कर रहे हैं NullPointerExceptionरों दिन भर। > :-(

इसके बाद निम्न कोड के साथ काम किया:

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();

मेरी इकाई कहाँ थी:

@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
}

2
हाइबरनेट के लिए अच्छा विकल्प।
javydreamercsw

8

सादे JPA के साथ, यह मानते हुए कि आपके पास एक PersistenceProviderकार्यान्वयन है (उदाहरण के लिए हाइबरनेट), आप PersistenceProvider # createContainerEntityManagerFactory (PersistenceUnitInfo जानकारी, मैप मैप) विधि का उपयोग कर सकते हैं ,EntityManagerFactory बिना जरूरत के बूटस्ट्रैप करने के लिए persistence.xml

हालाँकि, यह कष्टप्रद है कि आपको PersistenceUnitInfoइंटरफ़ेस लागू करना है, इसलिए आप स्प्रिंग या हाइबरनेट का उपयोग करना बेहतर मानते हैं जो दोनों persistence.xmlफाइल के बिना जेपीए बूटस्ट्रैपिंग का समर्थन करते हैं :

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

जहाँ PersistenceUnitInfo स्प्रिंग-विशिष्ट MutablePersistenceUnitInfo वर्ग द्वारा कार्यान्वित किया जाता है ।


का उपयोग कर MutablePersistenceUnitInfoकाम नहीं करता है क्योंकि कुछ तरीके UnsupportedOperationException को फेंक देते हैं । इसके अलावा उल्लिखित लेख थोड़ा पुराना है: getPersistenceUnitRootUrlअशक्त नहीं लौट सकता अन्यथा हाइबरनेट क्लासपाथ (हाइबरनेट 5.2.8) को स्कैन नहीं करता है।
ब्राइस

1
मैं थोड़ा गलत था, लेख उस संबंध में पुराना नहीं है क्योंकि कोड संस्थाओं की एक सूची से गुजर रहा है और पैकेज स्कैनिंग का उपयोग नहीं करता है। हालांकि ऑटो इकाई स्कैनिंग के लिए getPersistenceUnitRootUrl या तो इसे लागू करना आवश्यक है या getJarFileUrls। बाद में stackoverflow.com/a/42372648/48136
Brice

0

DataNucleus JPA है कि मैं भी अपने डॉक्स में यह करने का एक तरीका है का उपयोग करें । वसंत के लिए कोई ज़रूरत नहीं है, या बदसूरत कार्यान्वयन के लिए PersistenceUnitInfo

बस इस प्रकार करते हैं

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);

0

आप PersistenceContext या Autowired annotation का उपयोग करके एक EntityManager भी प्राप्त कर सकते हैं, लेकिन ध्यान रखें कि यह थ्रेड-सुरक्षित नहीं होगा।

@PersistenceContext
private EntityManager entityManager;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.