Log4j + OpenJPA = NoClassDefFoundError: javax/persistence/AttributeConverter - java

I'm trying to get log4j (I would also be happy to use any logging api as log as it is jpa persistent) use jpa appender.
My persistence.xml looks like this
<persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<class>org.apache.camel.processor.interceptor.jpa.JpaTraceEventMessage</class>
<class>org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapAttributeConverter</class>
<class>org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapJsonAttributeConverter</class>
<class>org.apache.logging.log4j.core.appender.db.jpa.converter.ContextStackAttributeConverter</class>
<class>org.apache.logging.log4j.core.appender.db.jpa.converter.ContextStackJsonAttributeConverter</class>
<class>org.apache.logging.log4j.core.appender.db.jpa.converter.MarkerAttributeConverter</class>
<class>org.apache.logging.log4j.core.appender.db.jpa.converter.MessageAttributeConverter</class>
<class>org.apache.logging.log4j.core.appender.db.jpa.converter.StackTraceElementAttributeConverter</class>
<class>org.apache.logging.log4j.core.appender.db.jpa.converter.ThrowableAttributeConverter</class>
<class>com.xxxxxx.lab.logging.ReportEntity</class>
<properties>
<property name="openjpa.jdbc.DBDictionary" value="org.apache.openjpa.jdbc.sql.HSQLDictionary"/>
<!-- value="buildSchema" to runtime forward map the DDL SQL; value="validate" makes no changes to the database -->
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/>
<property name="openjpa.RuntimeUnenhancedClasses" value="supported"/>
</properties>
</persistence-unit>
As per apidocs:
Many of the return types of LogEvent methods (e.g., StackTraceElement,
Message, Marker, Throwable, ThreadContext.ContextStack, and
Map) will not be recognized by the JPA provider. In
conjunction with #Convert, you can use the converters in the
org.apache.logging.log4j.core.appender.db.jpa.converter package to
convert these types to database columns.
So I added all necessary classes, but it still throws:
java.lang.NoClassDefFoundError: javax/persistence/AttributeConverter

AttributeConverter seems something new in JPA2.1. Are you sure your project is using JPA2.1 instead of any prior version?
Just curious, why are you so insists to use JPA for log persistence? There are plenty JDBC-based solution which works well. I don't see any reason for using JPA solution unless you are going to make use of the logging related entities in your application.

Related

hibernate search configuration

Im using hibernate search and elastic search as backend . When i config hibernate and hibernatesearch in xml file everything is ok but whene i config it in java class this warning occur and nothing found in my search .
xml config is:
<properties>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3399/elastic" />
<property name="hibernate.connection.username" value="admin" />
<property name="hibernate.connection.password" value="admin" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.search.default.indexmanager" value="elasticsearch"/>
<property name="hibernate.search.default.elasticsearch.host" value="http://127.0.0.1:9400"/>
<property name="hibernate.search.default.elasticsearch.index_schema_management_strategy" value="CREATE"/>
<property name="hibernate.search.default.elasticsearch.required_index_status" value="YELLOW"/>
</properties>
java class config is :
java.util.Properties settings = new java.util.Properties();
settings.put(org.hibernate.cfg.Environment.DRIVER, "com.mysql.cj.jdbc.Driver");
settings.put(org.hibernate.cfg.Environment.URL, "jdbc:mysql://127.0.0.1:3399/elastic");
settings.put(org.hibernate.cfg.Environment.USER, "admin");
settings.put(org.hibernate.cfg.Environment.PASS, "admin");
settings.put(org.hibernate.cfg.Environment.DIALECT,"org.hibernate.dialect.MySQL8Dialect");
settings.put(org.hibernate.cfg.Environment.SHOW_SQL, "true");
settings.put(org.hibernate.cfg.Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread");
settings.put(org.hibernate.cfg.Environment.POOL_SIZE, "5");
settings.put("hibernate.search.default.indexmanager", "elasticsearch");
settings.put("hibernate.search.default.elasticsearch.host", "http://127.0.0.1:9400");
settings.put("hibernate.search.default.elasticsearch.index_schema_management_strategy", "CREATE");
settings.put("hibernate.search.default.elasticsearch.required_index_status", "YELLOW");
Warning is :
WARNING: request [HEAD http://127.0.0.1:9400/com.radar.elasticsearch.videogame] returned 1 warnings: [299 Elasticsearch-6.8.0-65b6179 "[types removal] The parameter include_type_name should be explicitly specified in get indices requests to prepare for 7.0. In 7.0 include_type_name will default to 'false', which means responses will omit the type name in mapping definitions."]
You are using Elasticsearch 6.8 where types are deprecated. Please refer removal of types for more info,
You need to pass _doc instead of type name otherwise use include_type_name if you are using your own type name in all the API.
Please refer this official blog for more info
If you plan to upgrade without downtime in a rolling fashion, you
should upgrade to 6.8 first, which is the only 6.x release to have
some features like support for the include_type_name parameter, which
is required to upgrade to 7.0 smoothly.
Elasticsearch support in Hibernate Search 5 is experimental and was only tested with Elasticsearch up to version 5.6.
If you need to upgrade to Elasticsearch 7, upgrade to Hibernate Search 6.
Hibernate Search 6 is currently in Beta but offers revamped APIs that will be a much better fit for Elasticsearch.
It also offers new features not found in Hibernate Search 5, such as support for nested documents or the ability to inject JSON directly into your query (to take advantage of more exotic predicates/sorts/etc. not yet supported by the Hibernate Search DSL).
EDIT: Also, you can find information about the compatibility of Hibernate Search with various other components on this page of the official website.

Hibernate equivalent properties for these openjpa propertie

I have an requirement to use Hibernate Persistence instead of OpenJPA Persistence
I searched in google but didn't get information still looking on it.Any body help on this. I am not much expert in Hibernate.
<property name="openjpa.TransactionMode" value="managed"/>
<property name="openjpa.ConnectionRetainMode" value="always"/>

JPA variable persistence units

I'm trying to develop a website using java EE, which will be deployed to a remote server, i am trying to implement JPA into the application.
For testing purposes i'd like to create a variable persistence unit, so that on the local deployment, the application will use my local mySQL server, while on the remote deployment it will use the server's provided mySQL server.
the problem however is that i'm running on glassfish locally, and jboss remote, so i can't make the resource JNDI names for the datasources the same (since jboss requires "java:/" or "java:jboss/" as a prefix, while glassfish doesn't allow :'s in JNDI names)
another problem is that i'm not simply allowed to create 2 persistence units with the same name,
i've tried making 2 different persistence units, but then the deployment fails because one of the persistence units fails to resolve.
below is my persistence.xml at this time:
<persistence-unit name="LocalPU">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/website</jta-data-source>
<properties>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
<property name="eclipselink.ddl-generation.output-mode" value="both"/>
</properties>
</persistence-unit>
<persistence-unit name="RemotePU">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>java:/website</jta-data-source>
<properties>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
<property name="eclipselink.ddl-generation.output-mode" value="both"/>
</properties>
</persistence-unit>
so my question is, is it possible to have an entitymanager resolve to EITHER of these persistence units, but not require both persistence units to be available
EDIT:
about 5 minutes after posting this question, i found an article that suggests using environment variables
however this does not seem to work within glassfish,
this persistence.xml:
<persistence-unit name="LocalPU">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>${myds}</jta-data-source>
<properties>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
<property name="eclipselink.ddl-generation.output-mode" value="both"/>
</properties>
</persistence-unit>
and the JVM-option -Dmyds=jndi/website results in the following error:
Exception while preparing the app : Invalid resource : ${myds}__pm
com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Invalid resource : ${myds}__pm
which leads me to believe environment variables can't be parsed within glassfish (???)
after following the tips provided in the first comment above, i have concluded that the question is irrelevant, and that my issues were caused by my misunderstanding of how JNDI names are displayed/parsed differently between glassfish, jboss, and JPA (in my case this has switched to hibernate, since openshift's Jboss servers turned out not to support eclipselink after all)
Glassfish, names the JNDI resource as jdbc/website, yet parses it as java:jdbc/website
Jboss on the other hand, requires the "java:" prefix to be defined explicitly, so in order to adress the same data source, it should be named java:jdbc/website
i'm not entirely sure how JPA/Java EE parse the JNDI names internally, but it seems as though either version works, so both java:jdbc/website AND jdbc/website would succesfully connect to the datasource defined in both the glassfish and the jboss environment.
at least i've been able to succesfully build to both jboss and glassfish using the java:jdbc/website datasource name, and i've had the same result with jdbc/website

Hibernate entity manager looking for tables in different schemas

I am implementing jpa persistence using hiberante-entity manager in a java web project.
I have set following property in in persistence.xml.
<property name="hibernate.hbm2ddl.auto" value="update"/>
I have a schema for each user. For e.g i have a schema for user1 and one for user2.
If the table 'ABC' is present in user1 schema but not in user2 schema & I deploy the application and it uses user2 db credentials, i get the message 'user1.ABC' table found so the 'ABC' table is not created in user2 schema.
When i tried with following property in the persistence.xml file the table is created in the user2 schema.
<property name="hibernate.hbm2ddl.auto" value="create"/>
My question is
why hibernate is searching in another schema i.e user1 if the application is using user2 db credentials? and
I don't want to create the schema every time the server is started so how can i avoid using
the value 'create'.
EDIT: Below is my persistence.xml file
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="XXXXXX" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>org.axonframework.saga.repository.jpa.SagaEntry</class>
<class>org.axonframework.saga.repository.jpa.AssociationValueEntry</class>
<properties>
<property name="hibernate.archive.autodetection" value="class"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
Thanks in advance
I am also facing the same issue, and after digging a lot, get to know that the bug is related to the Mysql Connector.
After changing MySql Connector 6.0.5 to 5.1.28 It works fine for me.
I hope It can help you. Cheers
Has the same problem.
After set <property name="hibernate.default_schema" value="MY_SCHEMA"/> the problem has been solved.
Check if you are calling user1 and user2 in your Hibernate Sessionfactory.
If you want to handle several schemas properly then use multi-tenant per schema also if you want to update/create/migrate/handle columns/tables/schemas/databases then use flyway or liquibase
REFERENCES
Multitenancy https://vladmihalcea.com/hibernate-database-schema-multitenancy/
Flyway https://flywaydb.org
Liquibase https://www.liquibase.org
The Hibernate documentation is clear about this, you need to enable multi-tenant operations as described in this answer and this example.
Basically you have to declare multiple persistence units and have each point to a different schema. Each can then use different login credentials as well.
Hibernate documentation link
To summarise:
Define your persistence unit
Define your mapping files per persistence unit
When using JPA add the following:
3. Specifying tenant identifier from SessionFactory
4. Implement a MultiTenantConnectionProvider

HSQLdb permissions regarding OpenJPA

I'm (still) having loads of issues with HSQLdb & OpenJPA.
Exception in thread "main" <openjpa-1.2.0-r422266:683325 fatal store error> org.apache.openjpa.persistence.RollbackException: user lacks privilege or object not found: OPENJPA_SEQUENCE_TABLE {SELECT SEQUENCE_VALUE FROM PUBLIC.OPENJPA_SEQUENCE_TABLE WHERE ID = ?} [code=-5501, state=42501]
at org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:523)
at model_layer.EntityManagerHelper.commit(EntityManagerHelper.java:46)
at HSQLdb_mvn_openJPA_autoTables.App.main(App.java:23)
The HSQLdb is running as a server process, bound to port 9001 at my local machine. The user is SA. It's configured as follows:
<persistence-unit name="HSQLdb_mvn_openJPA_autoTablesPU"
transaction-type="RESOURCE_LOCAL">
<provider>
org.apache.openjpa.persistence.PersistenceProviderImpl
</provider>
<class>model_layer.Testobjekt</class>
<class>model_layer.AbstractTestobjekt</class>
<properties>
<property name="openjpa.ConnectionUserName" value="SA" />
<property name="openjpa.ConnectionPassword" value=""/>
<property name="openjpa.ConnectionDriverName"
value="org.hsqldb.jdbc.JDBCDriver" />
<property name="openjpa.ConnectionURL"
value="jdbc:hsqldb:hsql://localhost:9001/mydb" />
<!--
<property name="openjpa.jdbc.SynchronizeMappings"
value="buildSchema(ForeignKeys=true)" />
-->
</properties>
</persistence-unit>
I have made a successful connection with my ORM layer. I can create and connect to my EntityManager.
However each time I use
EntityManagerHelper.commit();
It fail with that error, which makes no sense to me. SA is the Standard Admin user I used to create the table. It should be able to persist as this user into hsqldb.
edit: after hours of debugging I found out why this fails. This kind of error message also appears if you do not set required table entries (NOT NULL). It didn't indicate that for me. It seems the OpenJPA layer mistakes not being able to insert statements because of missing entries for permission problems. I simply accepted the first answer therefore. Thanks for reading :)
I have the impressoin that HSQL has no rights to write its datafile in the configured directory.
That happens to me all the time when I test my server manually as root/Administrator and that when starting it as a daemon/service it changes to a less privileged user. Then the files are owned by another user as the server is running as.
It could be other reasons : on Windows I had it when another process (another server instance) was still clinging on to the files, or even when eclipse in its infinite wisdom decided to index the database.

Categories

Resources