Try it
Try it

Reputation: 315

AEM CQ with JPA (Hibernate)

I'm working with Adobe Experience Manager (AEM) 6.4 with Service Pack 1, and the Forms Package. I have a lot of extended Properties/attributes, so I made a Database diagram. I don't want to save all the additional stuff in crx I want to save it in an Oracle database.

The Database diagram is complex, so I want to USE JPA (Hibernate), at minimum. If Spring would help to make it easier to use, than that would be fine for me.

I read a lot that the OSGI is working with blueprint instead of Spring, but you can combine it.

I'm really searching for an good example how to make things work with JPA and a Oracle db.

Adobe is no Help at all, they can't show an example how to work with AEM and JPA/Hibernate/Spring/blueprint.

Can anybody help me to make things working? with AEM and JPA?

I think what I need is:

  1. persistence.xml (RESOURCE_LOCAL or JTA?)
  2. Entity classes with Annotation @Entity and other JPA annotations
  3. Service classes with Transaction control and maybe manager classes to submit to work with the entity classes and get result from queries, maybe I could put it all in the service classes
  4. hibernate-osgi (dependency)
  5. ojdbc7 for connection (dependency)
  6. org.apache.aries.jpa.api (dependency)

But how do I have to make things happen? Nothing works. I even don't know if this is the right way.

should I use blueprint or Spring or both?

I found this Aries thing from apache. http://aries.apache.org And weard different samples that I don't really understand how they work. https://github.com/apache/aries-jpa/tree/master/examples

And some OSGI sample, they look very incomplete for my situation. https://enroute.osgi.org/tutorial/032-tutorial_microservice-jpa.html

So is there anybody with some experience with AEM and JPA?

Upvotes: 4

Views: 1662

Answers (4)

Alex Markov
Alex Markov

Reputation: 1

We have integrated Hibernate 5.4.5 and JPA 2.2 into Adobe Experience Manager 6.4.4 using two approaches below. Please, check https://soft-werke.com/en/archives/news-en/how-to-install-hibernate-5-4-5-jpa-2-2-in-adobe-experience-manager-6-4-4/ for more details.

  1. Classic approach - install zip package with all embedded Hibernate dependencies in AEM Package Manager with content-package-maven-plugin. Below is an example of Maven profile which can be later excluded to avoid installing Hibernate in each AEM deployment.
<profiles>
    <profile>
        <id>installHibernate</id>
        <activation>
            <activeByDefault>false</activeByDefault>
        </activation>
        <build>
            <plugins>
                <plugin>
                    <groupId>com.day.jcr.vault</groupId>
                    <artifactId>content-package-maven-plugin</artifactId>
                    <extensions>true</extensions>
                    <configuration>
                        <embeddedTarget>/apps/hibernate/install</embeddedTarget>
                        <embeddeds>
                            <embedded>
                                <groupId>org.apache.servicemix.bundles</groupId>
                                <artifactId>org.apache.servicemix.bundles.antlr</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>com.fasterxml</groupId>
                                <artifactId>classmate</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>com.sun.activation</groupId>
                                <artifactId>javax.activation</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>javax.activation</groupId>
                                <artifactId>javax.activation-api</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>javax.persistence</groupId>
                                <artifactId>javax.persistence-api</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>javax.xml.bind</groupId>
                                <artifactId>jaxb-api</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>net.bytebuddy</groupId>
                                <artifactId>byte-buddy</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>org.apache.servicemix.bundles</groupId>
                                <artifactId>org.apache.servicemix.bundles.dom4j</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>com.sun.istack</groupId>
                                <artifactId>istack-commons-runtime</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>com.sun.xml.fastinfoset</groupId>
                                <artifactId>FastInfoset</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>org.apache.servicemix.bundles</groupId>
                                <artifactId>org.apache.servicemix.bundles.jaxb-runtime</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>org.javassist</groupId>
                                <artifactId>javassist</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>org.jboss.logging</groupId>
                                <artifactId>jboss-logging</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>org.hibernate.common</groupId>
                                <artifactId>hibernate-commons-annotations</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>org.jboss</groupId>
                                <artifactId>jandex</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>javax.el</groupId>
                                <artifactId>javax.el-api</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>org.apache.servicemix.bundles</groupId>
                                <artifactId>org.apache.servicemix.bundles.javax-inject</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>javax.interceptor</groupId>
                                <artifactId>javax.interceptor-api</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>javax.enterprise</groupId>
                                <artifactId>cdi-api</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>org.jboss.spec.javax.interceptor</groupId>
                                <artifactId>jboss-interceptors-api_1.2_spec</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>org.jboss.spec.javax.transaction</groupId>
                                <artifactId>jboss-transaction-api_1.2_spec</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>mysql</groupId>
                                <artifactId>mysql-connector-java</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>org.hibernate</groupId>
                                <artifactId>hibernate-core</artifactId>
                            </embedded>
                            <embedded>
                                <groupId>org.hibernate</groupId>
                                <artifactId>hibernate-osgi</artifactId>
                            </embedded>
                        </embeddeds>
                    </configuration>
                    <executions>
                        <execution>
                            <id>install-package-hibernate</id>
                            <goals>
                                <goal>install</goal>
                            </goals>
                            <configuration>
                                <targetURL>http://${aem.host}:${aem.port}/crx/packmgr/service.jsp</targetURL>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

<!-- ====================================================================== -->
<!-- D E P E N D E N C I E S                                                -->
<!-- ====================================================================== -->
<dependencies>
    <dependency>
        <groupId>org.apache.servicemix.bundles</groupId>
        <artifactId>org.apache.servicemix.bundles.antlr</artifactId>
        <version>2.7.7_5</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml</groupId>
        <artifactId>classmate</artifactId>
        <version>1.3.4</version>
    </dependency>
    <dependency>
        <groupId>com.sun.activation</groupId>
        <artifactId>javax.activation</artifactId>
        <version>1.2.0</version>
    </dependency>
    <dependency>
        <groupId>javax.activation</groupId>
        <artifactId>javax.activation-api</artifactId>
        <version>1.2.0</version>
    </dependency>
    <dependency>
        <groupId>javax.persistence</groupId>
        <artifactId>javax.persistence-api</artifactId>
        <version>2.2</version>
    </dependency>
    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.3.1</version>
    </dependency>
    <dependency>
        <groupId>net.bytebuddy</groupId>
        <artifactId>byte-buddy</artifactId>
        <version>1.9.11</version>
    </dependency>
    <dependency>
        <groupId>org.apache.servicemix.bundles</groupId>
        <artifactId>org.apache.servicemix.bundles.dom4j</artifactId>
        <version>2.1.1_1</version>
    </dependency>
    <dependency>
        <groupId>com.sun.istack</groupId>
        <artifactId>istack-commons-runtime</artifactId>
        <version>3.0.7</version>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.fastinfoset</groupId>
        <artifactId>FastInfoset</artifactId>
        <version>1.2.16</version>
    </dependency>
    <dependency>
        <groupId>org.apache.servicemix.bundles</groupId>
        <artifactId>org.apache.servicemix.bundles.jaxb-runtime</artifactId>
        <version>2.3.1_1</version>
    </dependency>
    <dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.24.0-GA</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.logging</groupId>
        <artifactId>jboss-logging</artifactId>
        <version>3.3.2.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate.common</groupId>
        <artifactId>hibernate-commons-annotations</artifactId>
        <version>5.1.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.jboss</groupId>
        <artifactId>jandex</artifactId>
        <version>2.0.5.Final</version>
    </dependency>
    <dependency>
        <groupId>javax.el</groupId>
        <artifactId>javax.el-api</artifactId>
        <version>2.2.5</version>
    </dependency>
    <dependency>
        <groupId>org.apache.servicemix.bundles</groupId>
        <artifactId>org.apache.servicemix.bundles.javax-inject</artifactId>
        <version>1_2</version>
    </dependency>
    <dependency>
        <groupId>javax.interceptor</groupId>
        <artifactId>javax.interceptor-api</artifactId>
        <version>1.2.2</version>
    </dependency>
    <dependency>
        <groupId>javax.enterprise</groupId>
        <artifactId>cdi-api</artifactId>
        <version>1.2</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.jboss.spec.javax.interceptor</groupId>
        <artifactId>jboss-interceptors-api_1.2_spec</artifactId>
        <version>1.0.1.Final</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.spec.javax.transaction</groupId>
        <artifactId>jboss-transaction-api_1.2_spec</artifactId>
        <version>1.1.1.Final</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.46</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.4.5.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-osgi</artifactId>
        <version>5.4.5.Final</version>
    </dependency>
    <dependency>
        <groupId>com.adobe.aem</groupId>
        <artifactId>uber-jar</artifactId>
        <classifier>apis</classifier>
    </dependency>
    <dependency>
        <groupId>javax.jcr</groupId>
        <artifactId>jcr</artifactId>
    </dependency>
</dependencies>
  1. Another approach - install all Hibernate bundles in AEM Felix Console one-by-one in predefined order with sling-maven-plugin called by Java Maven Invoker API. Below is an example of Maven profile.
<profiles>
    <profile>
        <id>installHibernate</id>
        <activation>
            <activeByDefault>false</activeByDefault>
        </activation>

        <dependencies>
            <dependency>
                <groupId>rg</groupId>
                <artifactId>com.softwerke.jpa.hibernate.bundles</artifactId>
                <version>1.0-SNAPSHOT</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-dependency-plugin</artifactId>
                    <executions>
                        <execution>
                            <id>copy</id>
                            <phase>package</phase>
                            <goals>
                                <goal>copy-dependencies</goal>
                            </goals>
                            <configuration>
                                <outputDirectory>
                                    ${basedir}/src/main/content/jcr_root/apps/hibernate/install/
                                </outputDirectory>
                                <includeArtifactIds>
                                    org.apache.servicemix.bundles.antlr,
                                    classmate,
                                    javax.activation,
                                    javax.activation-api,
                                    javax.persistence-api,
                                    jaxb-api,
                                    byte-buddy,
                                    org.apache.servicemix.bundles.dom4j,
                                    istack-commons-runtime,
                                    FastInfoset,
                                    org.apache.servicemix.bundles.jaxb-runtime,
                                    javassist,
                                    jboss-logging,
                                    hibernate-commons-annotations,
                                    jandex,
                                    javax.el-api,
                                    org.apache.servicemix.bundles.javax-inject,
                                    javax.interceptor-api,
                                    cdi-api,
                                    jboss-interceptors-api_1.2_spec,
                                    jboss-transaction-api_1.2_spec,
                                    mysql-connector-java,
                                    hibernate-core,
                                    hibernate-osgi
                                </includeArtifactIds>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>exec-maven-plugin</artifactId>
                    <version>1.6.0</version>
                    <executions>
                        <execution>
                            <phase>install</phase>
                            <goals>
                                <goal>java</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <mainClass>com.softwerke.build.utils.HibernateInstaller</mainClass>
                        <classpathScope>compile</classpathScope>
                        <arguments>
                            <!-- Path to load Hibernate OSGi dependencies from -->
                            <argument>${basedir}/src/main/content/jcr_root/apps/hibernate/install</argument>
                            <!-- Path to XML file with a list of Hibernate bundles -->
                            <argument>${basedir}/src/main/content/META-INF/resources/hibernate-bundles.xml</argument>
                            <!-- User login to install bundle in AEM -->
                            <argument>${sling.user}</argument>
                            <!-- User password to install bundle in AEM -->
                            <argument>${sling.password}</argument>
                            <!-- Path to AEM Felix Console -->
                            <argument>http://${aem.host}:${aem.port}/system/console</argument>
                        </arguments>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

Java code for Hibernate bundle installation with Maven Invoker API:

public class HibernateInstaller {
    public static void main(String[] args) throws Exception {
        String bundleFolder,
               xmlFilePath,
               slingUser,
               slingPassword,
               url;
        if (args != null && args.length == 5) {
            bundleFolder = args[0];
            xmlFilePath = args[1];
            slingUser = args[2];
            slingPassword = args[3];
            url = args[4];
        } else {
            throw new Exception("Can't execute Hibernate install!\nPlease specify five arguments.");
        }

        StringBuilder mvnCmd = new StringBuilder();
        mvnCmd.append("org.apache.sling:sling-maven-plugin:2.4.2:install-file");
        mvnCmd.append(" -Dsling.user=" + slingUser);
        mvnCmd.append(" -Dsling.password=" + slingPassword);
        mvnCmd.append(" -Dsling.url=" + url);
        mvnCmd.append(" -Dsling.deploy.method=WebConsole");
        mvnCmd.append(" -Dsling.file=");
        mvnCmd.append(bundleFolder);
        mvnCmd.append("/");

        // Read XML file with a list of the Hibernate OSGi dependencies (bundles)
        File file = new File(xmlFilePath);
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        Document document = documentBuilder.parse(file);
        NodeList bundlesList = document.getElementsByTagName("bundle");

        final InvocationRequest invocationRequest = new DefaultInvocationRequest();
        // invocationRequest.setDebug(true);
        final Invoker invoker = new DefaultInvoker();

        for (int i = 0; i < bundlesList.getLength(); i++) {
            String goal = mvnCmd.toString() + bundlesList.item(i).getTextContent();
            installBundle(invocationRequest, invoker, goal);
        }
    }

    private static void installBundle(InvocationRequest invocationRequest, Invoker invoker, String goal)
            throws MavenInvocationException, CommandLineException {
        invocationRequest.setGoals(Collections.singletonList(goal));
        final InvocationResult invocationResult = invoker.execute(invocationRequest);
        if (invocationResult.getExitCode() != 0) {
            String msg = "Invocation Exception";
            if (invocationResult.getExecutionException() != null) {
                msg = invocationResult.getExecutionException().getMessage();
            }
            throw new CommandLineException(msg);
        }
    }
}

P.S.

  1. In case you don't need different versions of same dependency on AEM instance, it's better to avoid using OSGi <Embed-Transitive>true</Embed-Transitive> as it might introduce security/performance/OSGi issues - see Embedding_Transitive_Dependencies_Into_a_Mega-Bundle_With_Maven-Bundle-Plugin for details.
  2. In case you once decide to switch to another ORM framework, it's better to prefer JPA EntityManagerFactory approach instead of Hibernate-specific SessionFactory - check https://stackoverflow.com/a/5640796/12547140.

Upvotes: 0

Try it
Try it

Reputation: 315

I've found the solution and made a post here on the site.

https://forums.adobe.com/message/10640295#10640295

I feel like I'm the First Guy on earth which combined AEM with JPA/Hibernate. Now I could check if it's a benefit to work with spring, to operate with the Transactions.

And those two who voted the question down, I'm sure you are from adobe --> thanks, now I feel more expert than you on your own cms, because before my post there was no solution for this problem.

Update: Maven Dependencies. If you have problems with the dependencies you have to Embed them and add the property "Embed-Transitive to true"

 <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <extensions>true</extensions>
            <inherited>true</inherited>
            <configuration>
                <instructions>
                    <Embed-Dependency>
                        *;scope=compile|runtime
                    </Embed-Dependency>
                    <Embed-Transitive>true</Embed-Transitive>
                    <Export-Package>
                        <!--TODO export packages -->

                    </Export-Package>
                    <Private-Package>todo</Private-Package>
                    <Import-Package>
                        <!-- Attention this is really sensitive!!. -->
                        *;resolution:="optional"
                    </Import-Package>
                    <Bundle-Activator>path.to.Activator</Bundle-Activator>
                </instructions>
            </configuration>
        </plugin>

Upvotes: 2

Evgeny Konstantinov
Evgeny Konstantinov

Reputation: 221

let me describe how it is implemented on our project. We are using AEM 6.3 with SP2. We have next dependencies in the root pom.xml:

    <!-- JPA -->
    <dependency>
        <groupId>org.hibernate.javax.persistence</groupId>
        <artifactId>hibernate-jpa-2.1-api</artifactId>
        <version>1.0.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.1.10.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>5.1.10.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate.common</groupId>
        <artifactId>hibernate-commons-annotations</artifactId>
        <version>5.0.1.Final</version>
    </dependency>
    <dependency>
        <groupId>com.ibm.db2.jcc</groupId>
        <artifactId>db2jcc4</artifactId>
        <version>11.1</version>
        <scope>system</scope>
        <systemPath>${project.root.path}/lib/db2jcc4.jar</systemPath>
    </dependency>
    <dependency>
        <groupId>org.jboss.logging</groupId>
        <artifactId>jboss-logging</artifactId>
        <version>3.3.2.Final</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml</groupId>
        <artifactId>classmate</artifactId>
        <version>1.3.0</version>
    </dependency>
    <dependency>
        <groupId>antlr</groupId>
        <artifactId>antlr</artifactId>
        <version>2.7.7</version>
    </dependency>
    <!-- local development database -->
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>1.4.194</version>
    </dependency>
    <!-- /JPA-->

Then we have the bundle to provide JPA dependencies and the OSGI service that allows to get hibernate Session. The bundle pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.myproject</groupId>
    <artifactId>myproject-bundles</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <artifactId>com.myproject.db</artifactId>
  <packaging>bundle</packaging>
  <name>myproject - DB bundle</name>
  <description>OSGI bundle to work with a database</description>

  <properties>
    <bundle.export>
      com.myproject.db.*,
      javax.persistence,
      org.hibernate,
      org.hibernate.cfg,
      org.hibernate.proxy,
      org.hibernate.boot.registry,
      org.hibernate.annotations,
      org.hibernate.service,
      org.hibernate.criterion,
      org.hibernate.transform
    </bundle.export>
    <bundle.import>*;resolution:=optional</bundle.import>
    <!-- Import JDBC driver dynamically -->
    <bundle.dynamic.import>com.ibm.*,javassist.util.*</bundle.dynamic.import>
    <bundle.embed>
      hibernate-jpa-2.1-api,hibernate-core,hibernate-entitymanager,hibernate-commons-annotations,jboss-logging,antlr
    </bundle.embed>
    <project.root.path>${project.basedir}/../..</project.root.path>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.hibernate.javax.persistence</groupId>
      <artifactId>hibernate-jpa-2.1-api</artifactId>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
    </dependency>
    <dependency>
      <groupId>org.hibernate.common</groupId>
      <artifactId>hibernate-commons-annotations</artifactId>
    </dependency>
    <dependency>
      <groupId>org.jboss.logging</groupId>
      <artifactId>jboss-logging</artifactId>
    </dependency>
    <dependency>
      <groupId>com.ibm.db2.jcc</groupId>
      <artifactId>db2jcc4</artifactId>
    </dependency>
    <dependency>
      <groupId>antlr</groupId>
      <artifactId>antlr</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
    </dependency>
      <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-annotations</artifactId>
      </dependency>
      <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
      </dependency>
      <dependency>
          <groupId>com.myproject</groupId>
          <artifactId>com.myproject.common</artifactId>
          <version>1.0-SNAPSHOT</version>
          <scope>compile</scope>
      </dependency>
  </dependencies>
</project>

In the bundle we have next service:

package com.myproject.db;

import org.hibernate.Session;

public interface JPASessionFactory {
    Session openSession();

    void closeSession(Session session);
}

implementation:

package com.myproject.db.impl;

import com.myproject.db.JPASessionFactory;
import org.apache.felix.scr.annotations.*;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;

import javax.sql.DataSource;
import java.util.Map;

@Service
@Component(metatype = true, policy = ConfigurationPolicy.REQUIRE)
@Properties({
        @Property(label = "Hibernate SQL dialect", name = Environment.DIALECT),
        @Property(label = "Show SQL", name = Environment.SHOW_SQL, boolValue = false),
        @Property(label = "Bulk ID Strategy", name = Environment.HQL_BULK_ID_STRATEGY)
})
public class JPASessionFactoryImpl implements JPASessionFactory {

    @Reference(target = "(datasource.name=myproject)")
    private DataSource dataSource;

    private SessionFactory sessionFactory;

    @Activate
    protected void activate(Map<String, Object> properties) {
        StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
                .configure()
                .applySetting(Environment.DIALECT, PropertiesUtil.toString(properties.get(Environment.DIALECT), ""))
                .applySetting(Environment.SHOW_SQL, PropertiesUtil.toBoolean(properties.get(Environment.SHOW_SQL), false))
                .applySetting(Environment.DATASOURCE, dataSource);

        String bulkIdStrategy = PropertiesUtil.toString(properties.get(Environment.HQL_BULK_ID_STRATEGY), "");
        if (!bulkIdStrategy.isEmpty()) {
            builder.applySetting(Environment.HQL_BULK_ID_STRATEGY, bulkIdStrategy);
        }
        sessionFactory = new Configuration().buildSessionFactory(builder.build());
    }

    @Deactivate
    protected void deactivate() {
        if (sessionFactory != null) {
            sessionFactory.close();
        }
    }

    @Override
    public Session openSession() {
        return sessionFactory.openSession();
    }

    @Override
    public void closeSession(Session session) {
        if (session != null && session.isOpen()) {
            session.close();
        }
    }
}

osgi config for the service:

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
          jcr:primaryType="sling:OsgiConfig"
          hibernate.dialect="org.hibernate.dialect.H2Dialect"
          hibernate.show_sql="{Boolean}true"/>

Configuration for DataSourceFactory apps/myproject-forms/configuration/config.local/org.apache.sling.datasource.DataSourceFactory-localh2.xml:

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
          jcr:primaryType="sling:OsgiConfig"
          datasource.name="myproject"
          driverClassName="org.h2.Driver"
          url="jdbc:h2:./myprojectlocal;AUTO_SERVER=TRUE"
          username="sa"
          password=""
          testOnBorrow="{Boolean}true"
          testOnReturn="{Boolean}true"
          testWhileIdle="{Boolean}true"
          validationQuery="SELECT 1"/>

Also we have the Hibernate config file hibernate.cfg.xml in "resources" folder of the bundle

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hbm2ddl.auto">update</property>
    <property name="current_session_context_class">thread</property>
    <mapping class="com.myproject.db.Entity1"/>
    <mapping class="com.myproject.db.Entity2"/>
  </session-factory>
</hibernate-configuration>

Upvotes: 2

Andre Albert
Andre Albert

Reputation: 1394

There are some blog posts describing how to realise JPA persistence in AEM/CQ. In using-jpa-to-write-database-applications-in-an-osgi-container-e-g-felix-or-adobe-aem-cq5 they describe how to setup a JNDI datasource with a PersistenceUnit and how to @Reference a EntityManagerFactory.

Upvotes: 0

Related Questions