Use of PersistenceContext in annotations - openjpa

Is it possible to use PersistenceContext as annotation for JPA in a normal JAVA class? If not, can you please tell me how to use the PersistenceContext without any annotation?

Yes, you can use #PersistenceContext in any Java class. However, you must specify annotation-config in your Spring configuration, as in the following example:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
</beans>
Once you have that specified, you can use #PersistenceContext as follows:
package com.sample.dao.impl
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class CustomerDaoImpl {
#PersistenceContext
private EntityManager em;
public Customer getCustomerByName(String customerName) {
Query query = em.createQuery("SELECT c FROM Customer c WHERE c.name = ?1");
query.setParameter(1, customerName);
List<Customer> results = query.getResultList();
if (results.size() > 0) {
return results.get(0);
}
return null;
}
}

Related

Unable to map List<String> by Hibernate in PostgreSql

I would like to do easy think - map list of String in database using hibernate.
I am able to do it when my hibernate.hbm2ddl.auto is set to create or create-drop.
If i change it to update it throws me an error during building Session Factory.
I checked that columns in db exists.
During debbuging it i found that in SchemaMigratorImpl.doMigrationToTargets Hibernate method
in field namespace primaryKey for table ITEM_POSITIONS is corrupted.
Does anyone know what i am doing wrong?
Stacktrace:
Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: HelloWorldPU] Unable to build Hibernate SessionFactory
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:877)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:805)
at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:58)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
at util.HibernateUtil.getEntityManagerFactory(HibernateUtil.java:43)
at TestApp.main(TestApp.java:12)
Caused by: org.hibernate.exception.SQLGrammarException: Error accessing column metadata: ITEM_POSITIONS
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:106)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:95)
at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.convertSQLException(InformationExtractorJdbcDatabaseMetaDataImpl.java:71)
at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.getForeignKeys(InformationExtractorJdbcDatabaseMetaDataImpl.java:631)
at org.hibernate.tool.schema.extract.internal.TableInformationImpl.foreignKeys(TableInformationImpl.java:88)
at org.hibernate.tool.schema.extract.internal.TableInformationImpl.getForeignKey(TableInformationImpl.java:99)
at org.hibernate.tool.schema.internal.SchemaMigratorImpl.findMatchingForeignKey(SchemaMigratorImpl.java:338)
at org.hibernate.tool.schema.internal.SchemaMigratorImpl.applyForeignKeys(SchemaMigratorImpl.java:318)
at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigrationToTargets(SchemaMigratorImpl.java:157)
at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigration(SchemaMigratorImpl.java:59)
at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:129)
at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:97)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:481)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:802)
... 5 more
Caused by: org.postgresql.util.PSQLException: ERROR: column t1.tgconstrname does not exists
Pozycja: 113
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2102)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1835)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:500)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:374)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:254)
at org.postgresql.jdbc2.AbstractJdbc2DatabaseMetaData.getImportedExportedKeys(AbstractJdbc2DatabaseMetaData.java:3373)
at org.postgresql.jdbc2.AbstractJdbc2DatabaseMetaData.getImportedKeys(AbstractJdbc2DatabaseMetaData.java:3566)
at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.getForeignKeys(InformationExtractorJdbcDatabaseMetaDataImpl.java:580)
... 16 more
Configuration:
Java 8
PostgreSql: postgresql-12.1-3-windows-x64
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>
<groupId>hibernatemapping</groupId>
<artifactId>hibernatemapping</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>7</source>
<target>7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.1-901.jdbc4</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.0.0.Final</version>
</dependency>
</dependencies>
</project>
persistence.xml:
<persistence
version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence_2_1.xsd">
<persistence-unit name="HelloWorldPU">
<class>domain.Item</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.use_sql_comments" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/hibernate_db?useSSL=false"/>
<property name="javax.persistence.jdbc.user" value="postgres"/>
<property name="javax.persistence.jdbc.password" value="admin"/>
</properties>
</persistence-unit>
</persistence>
HibernateUtil Class which is responsible for creating EntityManager:
package util;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.service.ServiceRegistry;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import java.util.Properties;
public class HibernateUtil {
private static SessionFactory sessionFactory;
private static EntityManagerFactory entityManagerFactory;
public static SessionFactory getSessionFactory() {
if (sessionFactory == null) {
try {
Configuration configuration = new Configuration();
// Hibernate settings equivalent to hibernate.cfg.xml's properties
Properties settings = new Properties();
settings.put(Environment.DRIVER, "org.postgresql.Driver");
settings.put(Environment.URL, "jdbc:postgresql://localhost:5432/hibernate_db?useSSL=false");
settings.put(Environment.USER, "postgres");
settings.put(Environment.PASS, "admin");
settings.put(Environment.SHOW_SQL, "true");
settings.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread");
settings.put(Environment.HBM2DDL_AUTO, "auto-update");
configuration.setProperties(settings);
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (Exception e) {
e.printStackTrace();
}
}
return sessionFactory;
}
public static EntityManagerFactory getEntityManagerFactory(){
if (entityManagerFactory == null) {
entityManagerFactory = Persistence.createEntityManagerFactory("HelloWorldPU");
}
return entityManagerFactory;
}
}
Entity class:
package domain;
import org.hibernate.annotations.Parameter;
import org.hibernate.annotations.*;
import javax.persistence.Entity;
import javax.persistence.*;
import java.util.*;
#Entity
public class Item {
#Id
#GeneratedValue(generator = "ID_GENERATOR")
#GenericGenerator(name = "ID_GENERATOR",
strategy = "enhanced-sequence",
parameters = {
#Parameter(name = "sequence_name",
value = "Item_sequence")
})
private Long id;
private String name;
#ElementCollection
#CollectionTable(name = "ITEM_POSITIONS")
#OrderColumn
#Column(name = "POSITIONS")
protected List<String> positions = new ArrayList<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getPositions() {
return positions;
}
public void setPositions(List<String> positions) {
this.positions = positions;
}
}
Test class:
import domain.Item;
import util.HibernateUtil;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import java.util.ArrayList;
import java.util.List;
public class TestApp {
public static void main(String[] args){
EntityManagerFactory emf = HibernateUtil.getEntityManagerFactory();
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
Item item = new Item();
item.setName("Item1");
List<String> positions = new ArrayList<>();
positions.add("Position1");
positions.add("Position2");
positions.add("Position3");
positions.add("Position4");
positions.add("Position5");
item.setPositions(positions);
em.persist(item);
transaction.commit();
em.close();
emf.close();
}
}
How to reproduce:
Run with property name="hibernate.hbm2ddl.auto" value="create"
Run with property name="hibernate.hbm2ddl.auto" value="update"
Set breakpoint in QueryExecutorImpl.receiveErrorResponse
Search invocation stack for SchemaMigratorImpl.doMigrationToTargets
I solved this issue.
I added this line to my pertsistence.xml
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
And i changed driver to:
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.5</version>
</dependency>

Unable to build entity manager factory - Rest Tomcat Jpa

I'm making a Restful web service using netbeans, tomcat, jpa and jax-rs. I have this error since I've add the <class /> tags to my persistence.xml for all of my classes (And I need them to make a select).
The error is : https://gist.github.com/anonymous/bb37c28cdb3dbdf721c5206bfa6369c3
And my persistence.xml is :
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="NataRestServicePU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>model.Media</class>
<class>model.MediaTypeDB</class>
<class>model.Message</class>
<class>model.Observation</class>
<class>model.Session</class>
<class>model.Species</class>
<class>model.User</class>
<class>model.UserType</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3307/natagora?zeroDateTimeBehavior=convertToNull"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.password" value="password"/>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
</properties>
</persistence-unit>
</persistence>
And this is the main dao (that worked before, didn't change anything) but without all the CRUD methods (just the read for example)
package dao;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
public class MainDAO<T> implements IMainDAO<T> {
protected Class<T> clazz;
private final EntityManagerFactory factory;
private static final String PERSISTENCE_UNIT_NAME = "NataRestServicePU";
#PersistenceContext(unitName = "NataRestServicePU")
protected EntityManager entityManager;
public MainDAO(Class<T> type){
clazz = type;
factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
}
public void setClazz(Class<T> clazzToSet) {
this.clazz = clazzToSet;
}
#Override
public T read(int id){
try{
newEntityManager();
return entityManager.find(clazz,id);
}finally{
closeEntityManager();
}
}
protected void closeEntityManager(){
entityManager.close();
}
protected void newEntityManager(){
entityManager = factory.createEntityManager();
}
}

Why EntityManager have null value in my dao layer?

I'm working on a Java EE 7 maven project I'm using wildfly 8.2 everything is okey the problem is when I create an entity manager using #PersistenceContext inside managedbeans (backing beans) that I use with my jsf the contanier create a entit manager object and it's work but when I try to use the entity maanger inside my DAO Layer it's not work the em stay have a null value and I don't know why this my code in my dao layer can someone helpe me ? .
dao interface :
public interface ICategoryDao {
Category addCategory(Category category);
void deleteCategory(Long codeCategory);
Set<Category> getAllCategories();
Category updateCategory(Category category);
}
dao impl :
#Named("categoryDao")
public class CategoryDao implements ICategoryDao{
private Logger log = Logger.getLogger(CategoryDao.class);
#PersistenceContext(unitName="BooksStore")
private EntityManager em ;
#Override
public Category addCategory(Category category) {
if(em==null)
{
log.info("em is null ");
return category;
}
em.getTransaction().begin();
em.persist(category);
em.getTransaction().commit();
log.info("CategoryDao : Object persisted." );
return category;
}
#Override
public void deleteCategory(Long codeCategory) {
// TODO Auto-generated method stub
}
#Override
public Set<Category> getAllCategories() {
// TODO Auto-generated method stub
return null;
}
#Override
public Category updateCategory(Category category) {
// TODO Auto-generated method stub
return null;
}
}
this is my beans.xml
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="all">
</beans>
My persistance.xml file :
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="BooksStore" transaction-type="JTA">
<jta-data-source>java:/bookstore</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
Do you have a persistence.xml file ?
This is an example for persistence.xml file :
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="School_Manager" transaction-type="RESOURCE_LOCAL">
<class>YourEntityFQN</class>
<properties>
attribute name on persistence.xml file must be "BooksStore" in your case .
In class tag you need to specify all entity that you want use for this persistence-unit .

Get Date of Database with JPQL

I have the next code:
package co.com.patios.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
#Entity
public class Date {
private java.util.Date dateActual;
#Id
#Column(name = "date")
#Temporal(TemporalType.DATE)
public java.util.Date getDateActual() {
return dateActual;
}
public void setDateActual(java.util.Date dateActual) {
this.dateActual = dateActual;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="PatiosDS">
<jta-data-source>java:jboss/datasources/PatiosDS</jta-data-source>
<class>co.com.patios.entity.Date</class>
<class>co.com.patios.entity.EntradaVehiculoPatio</class>
<class>co.com.patios.entity.EstadoVehiculo</class>
<class>co.com.patios.entity.MarcaVehiculo</class>
<class>co.com.patios.entity.ModeloVehiculo</class>
<class>co.com.patios.entity.Patio</class>
<class>co.com.patios.entity.Usuario</class>
<class>co.com.patios.entity.Vehiculo</class>
<properties>
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.default_schema" value="public" />
<property name="hibernate.transaction.jta.platform"
value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" />
</properties>
</persistence-unit>
My problem is the annotation #Entity, that show the next message
Table "Date" cannot be resolved
where I have the next line "co.com.patios.entity.Date" in the my file persistence.xml
I want to know, what could be the problem ?
Note: The code run correct, but show the message
Table "Date" cannot be resolved
and it show in eclipse like error

Cannot use an EntityTransaction while using JTA

I'm receiving this error:
javax.servlet.ServletException: java.lang.IllegalStateException:
Exception Description: Cannot use an EntityTransaction while using JTA.
While trying to use JPA and JAVAEE, Glassfish.
My persistence.xml file is as follow:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="acmeauction">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/MySQLJDBCResource</jta-data-source>
<class>it.uniroma3.acme.auction.model.User</class>
<class>it.uniroma3.acme.auction.model.Auction</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/acmeauction"/>
<property name="javax.persistence.jdbc.user" value="user"/>
<property name="javax.persistence.jdbc.password" value="password"/>
</properties>
</persistence-unit>
</persistence>
What i'm trying to do is to persist an object (User), in this way:
#ManagedBean
public class UserRepository implements Serializable{
#PersistenceUnit
EntityManagerFactory emf;
#PersistenceContext
private EntityManager em;
private static UserRepository instance;
/**
* Gives back the singleton UserRepository singleton.
*/
public static UserRepository getInstance() {
if (instance==null) {
instance = new UserRepository();
}
return instance;
}
private UserRepository() {
emf = Persistence.createEntityManagerFactory("acmeauction");
em = emf.createEntityManager();
}
/**
* Save and persist a new User.
*/
public void save(User user) {
em.getTransaction().begin();
em.persist(user);
em.getTransaction().commit();
}
}
While if it try to use UserRepository from a simple Java application, it works correctly.
Thanks in advance,
AN
You are not supposed to use em.getTransaction().begin(); nor em.getTransaction().commit();, these instructions are to be used with RESOURCE_LOCAL transaction type.
In your case the transaction is managed by the container, in the first use of the EntitiyManager in your method, the container checks whether there is an active transaction or not, if there is no transaction active then it creates one, and when the method call ends, the transaction is committed by the container. So, at the end your method should look like this:
public void save(User user) {
em.persist(user);
}
The container takes care of the transaction, that is JTA.
As the error states, if you are using JTA for transactions, you need to use JTA.
Either use JTA UserTransaction to begin/commit the transaction, or use a RESOURCE_LOCAL persistence unit and non-jta DataSource.
See,
http://en.wikibooks.org/wiki/Java_Persistence/Transactions