我正在使用带有Service Pack 1的Adobe Experience Manager(AEM)6.4和Forms Package。我有很多扩展的属性/属性,所以我制作了一个数据库图表。我不想在crx中保存所有其他东西我想将它保存在Oracle数据库中。
数据库图很复杂,所以我想至少使用JPA(Hibernate)。如果Spring有助于使它更容易使用,那对我来说没问题。
我读了很多OSGI正在使用蓝图而不是Spring,但你可以将它结合起来。
我正在寻找一个很好的例子,说明如何使用JPA和Oracle数据库。
Adobe根本没有帮助,他们无法展示如何使用AEM和JPA / Hibernate / Spring / blueprint的示例。
任何人都可以帮我把东西搞定吗?与AEM和JPA?
我想我需要的是:
但是我该如何让事情发生呢?什么都行不通。我甚至不知道这是不是正确的方法。
我应该使用蓝图还是Spring或两者兼而有之?
我从阿帕奇那里找到了这个白羊座的东西。 http://aries.apache.org和不同的样品,我真的不明白它们是如何工作的。 https://github.com/apache/aries-jpa/tree/master/examples
还有一些OSGI样本,它们看起来非常不完整。 https://enroute.osgi.org/tutorial/032-tutorial_microservice-jpa.html
那么有没有人有AEM和JPA的经验?
让我来描述它是如何在我们的项目中实现的。我们正在使用AEM 6.3和SP2。我们在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-->
然后我们让bundle提供JPA依赖项和允许获得hibernate Session的OSGI服务。包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>
在捆绑中我们有下一个服务:
package com.myproject.db;
import org.hibernate.Session;
public interface JPASessionFactory {
Session openSession();
void closeSession(Session session);
}
执行:
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配置服务:
<?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"/>
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"/>
我们还在捆绑包的“resources”文件夹中有Hibernate配置文件hibernate.cfg.xml
<?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>
我找到了解决方案并在网站上发了帖子。
https://forums.adobe.com/message/10640295#10640295
我觉得我是地球上第一个将AEM与JPA / Hibernate结合起来的人。现在,我可以检查使用spring是否有利于使用Transactions进行操作。
而那两个投票的人,我相信你是来自adobe - >谢谢,现在我觉得你自己的cms比你更专业,因为在我的帖子之前没有解决这个问题的方法。
更新:Maven依赖项。如果您对依赖项有疑问,则必须嵌入它们并添加属性“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>
有一些博客文章描述了如何在AEM / CQ中实现JPA持久性。在using-jpa-to-write-database-applications-in-an-osgi-container-e-g-felix-or-adobe-aem-cq5中,他们描述了如何使用PersistenceUnit设置JNDI数据源以及如何@Reference一个EntityManagerFactory。