TomEE + OpenJPA: Error creating EntityManager using container managed DataSource - java

I'm trying to configure an example JPA application in Eclipse, and deploy it to TomEE+. The datasource is container managed. I keep seeing the following error when attempting to create the EntityManager:
The persistence provider is attempting to use properties in the persistence.xml file to resolve the data source. A Java Database Connectivity (JDBC) driver or data source class name must be specified in the openjpa.ConnectionDriverName or javax.persistence.jdbc.driver property. The following properties are available in the configuration: "org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl#414793b4".
Any idea what is wrong with this configuration?
Below is the code.
tomee.xml
<tomee>
<Resource id="jdbc/MyAppDS" type="DataSource">
JdbcDriver com.microsoft.sqlserver.jdbc.SQLServerDriver
JdbcUrl jdbc:sqlserver://localhost:1433/db_dev
UserName user
Password password
JtaManaged true
DefaultAutoCommit false
</Resource>
</tomee>
persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.0">
<persistence-unit name="Simplest" transaction-type="JTA">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jta-data-source>jdbc/MyAppDS</jta-data-source>
<class>social.Media</class>
</persistence-unit>
</persistence>
Media.java
package social;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "media")
public class Media {
#Id
#Column(name = "id")
private String id;
private String description;
private String title;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
Controller.java
package social;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
#Path("/hello")
public class Controller {
#Inject private Media media;
#GET
#Produces(MediaType.TEXT_PLAIN)
public String sayHello() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("Simplest");
EntityManager em = emf.createEntityManager(); // exception reported on this line
.
.
.
return media.getDescription();
}
}

You are using JTA-managed Entity Manager Factory, I think that instead of manual creation of EntityManagerFactory you should let application server do it for you, like this in controller:
#Path("/hello")
public class Controller {
#PersistenceContext(unitName="Simplest")
private EntityManager em;
#GET
#Produces(MediaType.TEXT_PLAIN)
public String sayHello() {
// get Media from database - replace with your own code
Media media = em.find(Media.class, "1");
return media.getDescription();
}
}

Related

OpenJPA & Spring Boot 2 & Gradle

I'm trying to run OpenJPA with newest Spring Boot 2 and Gradle.
The problem is that Spring 5 does not support OpenJPA anymore.
When I run the application I see an error:
Caused by: org.apache.openjpa.persistence.ArgumentException: This configuration disallows runtime optimization, but the following listed types were not enhanced at build time or at class load time with a javaagent: "
aero.onair.accground.aft.TestEntity".
There was some plugin for older Gradle which was doing the entity enhancement with the use of openjpa library, but it does not work with the newer.
I have used an adapter and dialect like in this repo:
https://github.com/apache/syncope/tree/master/core/persistence-jpa/src/main/java/org/springframework/orm/jpa/vendor
I have the persistence.xml file in resources/jpa/persistence.xml
I have also tried to move it to resources/META-INF/
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
version="2.0">
<persistence-unit name="aftDbUnitName">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<class>aero.onair.accground.aft.TestEntity</class>
</persistence-unit>
</persistence>
My configuration for OpenJPA:
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.apache.openjpa.persistence.PersistenceProviderImpl;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
import org.springframework.transaction.jta.JtaTransactionManager;
#Configuration
public class OpenJpaConfig extends JpaBaseConfiguration {
protected OpenJpaConfig(DataSource dataSource,
JpaProperties properties,
ObjectProvider<JtaTransactionManager> jtaTransactionManager,
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
super(dataSource, properties, jtaTransactionManager, transactionManagerCustomizers);
}
#Override
protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
OpenJpaVendorAdapter jpaVendorAdapter = new OpenJpaVendorAdapter();
jpaVendorAdapter.setShowSql(true);
return jpaVendorAdapter;
}
#Override
protected Map<String, Object> getVendorProperties() {
return new HashMap<>(0);
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setDataSource(getDataSource());
factory.setPersistenceProviderClass(PersistenceProviderImpl.class);
factory.setJpaVendorAdapter(new OpenJpaVendorAdapter());
factory.setPersistenceXmlLocation("jpa/persistence.xml");
return factory;
}
}
Test Entity:
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class TestEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
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;
}
}
And finally the main Application class:
#SpringBootApplication(exclude = {XADataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
#Slf4j
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Autowired
TestEntitiyRepository testEntitiyRepository;
#PostConstruct
public void test() {
long count = testEntitiyRepository.count();
log.info("Count = {}", count);
TestEntity entitiy = new TestEntity();
entitiy.setName("testtttt");
testEntitiyRepository.save(entitiy);
count = testEntitiyRepository.count();
log.info("Count after save = {}", count);
}
}
The best solution for me was to add a plugin from this page:
https://github.com/radcortez/openjpa-gradle-plugin
Another solution is to set a javaagent in VM options:
-javaagent:/path/openjpa-all-3.1.0.jar

Java Hibernate attributeoverride annotation not working?

Hi I am currently learning Hibernate and I am stuck on a problem where I am trying to override the column name from address to home address and office address. I commented out all office-address code, but the column in database are still "CITY_NAME", "STREET_NAME" and etc.
Could someone please explain this, thanks.
Address.java
package org.zm.javabrain.dto;
import javax.persistence.Column;
import javax.persistence.Embeddable;
#Embeddable
public class Address {
#Column(name="STREET_NAME")
private String stree;
#Column(name="CITY_NAME")
private String city;
#Column(name="STATE_NAME")
private String state;
#Column(name="ZIP_NAME")
private String zip;
public String getStree() {
return stree;
}
public void setStree(String stree) {
this.stree = stree;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
}
this is UserDetails.java
package org.zm.javabrain.dto;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
#Entity // change the name of the entity
#Table(name="USER_DETAILS") // change the name of the table
public class UserDetails implements Serializable {
#Id #GeneratedValue(strategy=GenerationType.AUTO)
private int userId;
private String username;
private Date joinedDate;
private String description;
#Embedded
#AttributeOverrides({
#AttributeOverride(name="street",column=#Column(name="HOME_STREET_NAME")),
#AttributeOverride(name="city",column=#Column(name="HOME_CITY_NAME")),
#AttributeOverride(name="state",column=#Column(name="HOME_STATE_NAME")),
#AttributeOverride(name="zip",column=#Column(name="HOME_ZIP_NAME"))})
private Address homeAddress;
// #Embedded
// #AttributeOverrides({
// #AttributeOverride(name="street",column=#Column(name="OFFICE_STREET_NAME")),
// #AttributeOverride(name="city",column=#Column(name="OFFICE_CITY_NAME")),
// #AttributeOverride(name="state",column=#Column(name="OFFICE_STATE_NAME")),
// #AttributeOverride(name="zip",column=#Column(name="OFFICE_ZIP_NAME"))})
// private Address officeAddress;
//
// public Address getOfficeAddress() {
// return officeAddress;
// }
// public void setOfficeAddress(Address officeAddress) {
// this.officeAddress = officeAddress;
// }
public Date getJoinedDate() {
return joinedDate;
}
public void setJoinedDate(Date joinedDate) {
this.joinedDate = joinedDate;
}
public Address getHomeAddress() {
return homeAddress;
}
public void setHomeAddress(Address homeAddress) {
this.homeAddress = homeAddress;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
This is driver class
package org.zm.hibernate;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.zm.javabrain.dto.Address;
import org.zm.javabrain.dto.UserDetails;
public class HibernateTest {
public static void main(String[] args) {
UserDetails user = new UserDetails();
Address addr = new Address();
addr.setCity("chicago");
addr.setState("IL");
addr.setStree("Michigen Ave");
addr.setZip("55414");
Address officeAddr = new Address();
officeAddr.setCity("minneapolis");
officeAddr.setState("Washington Ave");
officeAddr.setState("MN");
officeAddr.setZip("55455");
user.setUsername("11111");
user.setHomeAddress(addr);
// user.setOfficeAddress(officeAddr);
user.setJoinedDate(new Date());
user.setDescription("this is a description");
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(user);
session.getTransaction().commit();
session.close();
}
}
I cannot tell you if Hibernate Session supports the AttributeOverride feature or not. The problem is, I guess, Hibernate is mixing two different technologies that are trying to solve the same problem, and that is confusing for new users trying to learn. Hibernate can be used as
Legacy (Native) ORM , and
JPA (Java Persistence API) implementation
As I can see from your posted code example that you are using JPA annotations. All annotations, classes and properties having the package structure of javax.persistence are JPA specific. So my advice is, either configure your persistence the Hibernate way or the JPA way, and don't mix.
If you want to map your entities the JPA way, do the following:
Put your configuration information in the file persistence.xml instead of in the hibernate.cfg.xml. The file should be under META-INF folder of your source directory. If you are using Maven put it under src/main/resources/META-INF directory. The file should look like:
<persistence 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"
version="2.1">
<persistence-unit name="yourPU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>org.zm.javabrain.dto.UserDetails</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="..." />
<property name="javax.persistence.jdbc.url" value="..." />
<property name="javax.persistence.jdbc.user" value="..." />
<property name="javax.persistence.jdbc.password" value="..." />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
</properties>
</persistence-unit>
</persistence>
replace the ... with correct database information.
In your test class (HibernateTest) do the following instead of SessionFactory / Session:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("yourPU");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(user);
em.getTransaction().commit;
em.close();
emf.close();
You can also read:
Hibernate User Guide
Java Persistence API Tutorials
JPA 2.1 Specification
Hopefully, it helps.

Hibernate Not retrieving the data

Iam trying to build a sample application with JAXRS/Hibernate.
I have sample data in my database,but i could not retrieve it.Please verify my code and let me know where Iam making error.
Entity class
package org.cricket.cricketstats.data;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Table(name="player_info")
#Entity
public class PlayerInfo {
#Id
#Column(name="player_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long playerId;
#Column(name="player_name")
private String playerName;
#Column(name="player_role")
private String playerRole;
#Column(name="player_batting_style")
private String playerBattingStyle;
#Column(name="player_bowling_style")
private String playerBowlingStyle;
#Column(name="player_image")
private String playerImage;
#Column(name="player_profile_desc")
private String playerProfile;
public PlayerInfo(){
}
public PlayerInfo(long playerId, String playerName, String playerRole, String playerBattingStyle,
String playerBowlingStyle, String playerImage, String playerProfile) {
super();
this.playerId = playerId;
this.playerName = playerName;
this.playerRole = playerRole;
this.playerBattingStyle = playerBattingStyle;
this.playerBowlingStyle = playerBowlingStyle;
this.playerImage = playerImage;
this.playerProfile = playerProfile;
}
public long getPlayerId() {
return playerId;
}
public void setPlayerId(long playerId) {
this.playerId = playerId;
}
public String getPlayerName() {
return playerName;
}
public void setPlayerName(String playerName) {
this.playerName = playerName;
}
public String getPlayerRole() {
return playerRole;
}
public void setPlayerRole(String playerRole) {
this.playerRole = playerRole;
}
public String getPlayerBattingStyle() {
return playerBattingStyle;
}
public void setPlayerBattingStyle(String playerBattingStyle) {
this.playerBattingStyle = playerBattingStyle;
}
public String getPlayerBowlingStyle() {
return playerBowlingStyle;
}
public void setPlayerBowlingStyle(String playerBowlingStyle) {
this.playerBowlingStyle = playerBowlingStyle;
}
public String getPlayerImage() {
return playerImage;
}
public void setPlayerImage(String playerImage) {
this.playerImage = playerImage;
}
public String getPlayerProfile() {
return playerProfile;
}
public void setPlayerProfile(String playerProfile) {
this.playerProfile = playerProfile;
}
}
Rest Resource
package org.cricket.cricketstats.resources;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.cricket.cricketstats.data.PlayerInfoDAO;
import org.cricket.cricketstats.model.PlayerInfoBean;
#Path("players")
public class CricketResources {
PlayerInfoBean playerInfoBean= new PlayerInfoBean();
#GET
#Path("{playerId}")
#Produces(MediaType.APPLICATION_JSON)
public PlayerInfoBean getPlayerDetails(#PathParam("playerId") long id) {
PlayerInfoDAO dao= new PlayerInfoDAO();
dao.getPlayerInfo();
playerInfoBean.setPlayerId(id);
return playerInfoBean;
}
}
Config file
<?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>
<!-- Connection settings -->
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
<property name="hibernate.connection.url">jdbc:postgresql://localhost:5432/cricket</property>
<property name="hibernate.connection.username">postgres</property>
<property name="hibernate.connection.password">postgres</property>
<!-- SQL dialect -->
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<!-- Print executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- validate all database on startup -->
<property name="hibernate.hbm2ddl.auto">validate</property>
<!-- Annotated entity classes -->
<mapping class="org.cricket.cricketstats.data.PlayerInfo"/>
</session-factory>
</hibernate-configuration>
DAO class
package org.cricket.cricketstats.data;
import java.util.List;
import org.cricket.cricketstats.model.PlayerInfoBean;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
public class PlayerInfoDAO {
public void getPlayerInfo(){
Configuration config=new Configuration().configure();
ServiceRegistry serviceRegistry= new StandardServiceRegistryBuilder().applySettings(config.getProperties()).build();
//StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(config.getProperties());
// SessionFactory factory = config.buildSessionFactory(builder.build());
SessionFactory factory = config.buildSessionFactory(serviceRegistry);
Session session = factory.openSession();
Transaction tx =session.beginTransaction();
List infoList=session.createQuery("FROM PlayerInfo").list();
tx.commit();
session.close();
System.out.println(infoList.get(0).getPlayerName());
}
}
**I have tried to give full path also in query **
The way is used by you to building a session factory is not correct for Hibernate 5. It can be used only for Hibernate 4.
Use this instead
SessionFactory factory = new Configuration().configure().buildSessionFactory();

Why this REST service is not working?

package model;
import java.net.URI;
import java.util.Collection;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.ws.rs.BadRequestException;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
#Path("/item")
#Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
#Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
#Stateless
public class InfoRestService {
// the PersistenceContext annotation is a shortcut that hides the fact
// that, an entity manager is always obtained from an EntityManagerFactory.
// The peristitence.xml file defines persistence units which is supplied by
// name
// to the EntityManagerFactory, thus dictating settings and classes used by
// the
// entity manager
#PersistenceContext(unitName = "Task")
private EntityManager em;
// Inject UriInfo to build the uri used in the POST response
#Context
private UriInfo uriInfo;
#POST
public Response createItem(PersonInfo item) {
if (item == null) {
throw new BadRequestException();
}
em.persist(item);
// Build a uri with the Item id appended to the absolute path
// This is so the client gets the Item id and also has the path to the
// resource created
URI itemUri = uriInfo.getAbsolutePathBuilder().path(item.getId()).build();
// The created response will not have a body. The itemUri will be in the
// Header
return Response.created(itemUri).build();
}
#GET
#Path("{id}")
public Response getItem(#PathParam("id") String id) {
PersonInfo item = em.find(PersonInfo.class, id);
if (item == null) {
throw new NotFoundException();
}
return Response.ok(item).build();
}
// Response.ok() does not accept collections
// But we return a collection and JAX-RS will generate header 200 OK and
// will handle converting the collection to xml or json as the body
#GET
public Collection<PersonInfo> getItems() {
TypedQuery<PersonInfo> query = em.createNamedQuery("PersonInfo.findAll",
PersonInfo.class);
return query.getResultList();
}
#PUT
#Path("{id}")
public Response updateItem(PersonInfo item, #PathParam("id") String id) {
if (id == null) {
throw new BadRequestException();
}
// Ideally we should check the id is a valid UUID. Not implementing for
// now
item.setId(id);
em.merge(item);
return Response.ok().build();
}
#DELETE
#Path("{id}")
public Response deleteItem(#PathParam("id") String id) {
PersonInfo item = em.find(PersonInfo.class, id);
if (item == null) {
throw new NotFoundException();
}
em.remove(item);
return Response.noContent().build();
}
}
package model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
/**
* The persistent class for the person_info database table.
*
*/
#Entity
#XmlRootElement
#Table(name="person_info")
#NamedQuery(name="PersonInfo.findAll", query="SELECT p FROM PersonInfo p")
public class PersonInfo implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private String id;
private String email;
#Column(name="first_name")
private String firstName;
#Column(name="last_name")
private String lastName;
public PersonInfo() {
}
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
persistence.xml
<?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="Task">
<jta-data-source>jdbc/DBtest</jta-data-source>
<class>model.PersonInfo</class>
</persistence-unit>
</persistence>
and the other class is Application
package model;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
#ApplicationPath("rest")
public class ApplicationConfig extends Application{
}
I really have no idea, the connections are made ok .. I'm using Glassfish 4 server and MySQL database... code is deploying but when I want to access the localhost:8080/Task/.. (my app) the only thing it says is this:
"HTTP Status 404 - Not Found / Type Status report
messageNot Found
descriptionThe requested resource is not available."
The code you supplied is working (when commenting out the persistence related stuff), I guess you are just confusing something.
The #ApplicationPath annotation sets the root context which comes after your project name.
If you project name really is Task you have to use this URL: http://localhost:8080/Task/rest/item
Otherwise: http://localhost:8080/YOUR_PROJECT_NAME/rest/item
See also:
How to set up JAX-RS Application using annotations only (no web.xml)?

Object persistence doesn't work

I'm trying to implement a little chat with JPA. Everythings work except one thing. I want, when my user open the connection with the endPoint, save his room number, his nickname and the timstamp.
My table has been well created, columns too but i cant persist my Connexion Object in DataBase.
I'm using Glasfish 4.0 and i've already create my JDBCRessources and JDBC Connection pools who are worked well.
Here my ChatEndPoint.Java
package server;
import java.io.IOException;
import javax.websocket.EncodeException;
import javax.websocket.EndpointConfig;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
#ServerEndpoint(value = "/websocket/{room-name}/{nick-name}", encoders = { ChatMessageEncoder.class }, decoders = { ChatMessageDecoder.class })
public class ChatEndPoint {
// traitement de la connexion d'un client
#OnOpen
public void open(Session session, EndpointConfig conf, #PathParam("room-name") String roomName, #PathParam("nick-name") String nickName) throws Exception {
System.out.println("connection ouverte");
session.getUserProperties().put("salle", roomName);
DAO dao=new DAO();
dao.createConnection(nickName, roomName);
}
// traitement de la reception d'un message client
#OnMessage
public void onMessage(Session session, ChatMessage msg) throws IOException,
EncodeException {
if (msg instanceof ChatMessage) {
ChatMessage reponse = new ChatMessage(msg.getEmetteur(),
msg.getSalle(), msg.getMessage());
for (Session sess : session.getOpenSessions()) {
if (sess.isOpen()
&& sess.getUserProperties().get("salle")
.equals(msg.getSalle()))
sess.getBasicRemote().sendObject(reponse);
}
}
}
}
My Connexion class who represent my entity to save :
Connexion.java
package server;
import java.io.Serializable;
import java.sql.Timestamp;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
#Entity
public class Connexion implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
#Column( name = "nickName" )
protected String nickName;
#NotNull
#Column( name = "roomName" )
protected String roomName;
#Column( name = "dateConnexion" )
protected Timestamp connectionDate;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getRoomName() {
return roomName;
}
public void setRoomName(String roomName) {
this.roomName = roomName;
}
public Timestamp getConnectionDate() {
return connectionDate;
}
public void setConnectionDate(Timestamp timestamp) {
this.connectionDate = timestamp;
}
}
DAO.java
package server;
import java.sql.Timestamp;
import javax.ejb.LocalBean;
import javax.ejb.Stateful;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;
#Stateless
#LocalBean
public class DAO {
#PersistenceUnit
private EntityManagerFactory emf;
// Injection du manager, qui s'occupe de la connexion avec la BDD
#PersistenceContext(unitName="projetwebee1")
EntityManager em;
// Enregistrement d'un nouvel utilisateur
public void createConnection(String nickName, String roomName) throws Exception{
this.emf=Persistence.createEntityManagerFactory("projetwebee1");
this.em = this.emf.createEntityManager();
Connexion c = new Connexion();
c.setNickName(nickName);
c.setRoomName(roomName);
c.setConnectionDate(new Timestamp((new java.util.Date()).getTime()));
System.out.println(" "+em);
em.persist(c);
System.out.println("persist OK");
}
}
persistence.xml generated by JPA. But i edited some part of it
<?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="projetwebee1" transaction-type="JTA">
<jta-data-source>JEEProjectJNDIFinal3</jta-data-source>
<properties>
<property name="eclipselink.ddl-generation" value="create-tables" />
</properties>
</persistence-unit>
</persistence>
So after i'm trying to persist my entity i cant see it in my data Explorer. I've already try a lot of other method than i found on the official doc or even here. But no one succeed.
Thanks for your help
The EJB container injects an entity manager in your bean, but you discard it and replace it by one you create yourself. All you need is
#Stateless
#LocalBean
public class DAO {
#PersistenceContext
EntityManager em;
public void createConnection(String nickName, String roomName) {
Connexion c = new Connexion();
c.setNickName(nickName);
c.setRoomName(roomName);
c.setConnectionDate(new Timestamp((new java.util.Date()).getTime()));
em.persist(c);
}
But the problem is that instead of letting the container create this EJB, you instanciate it by yourself, transforming what should be an injectable, transactional EJB into a dumb object, unmanaged by the EJB container. NEVER use new to get an instance of an EJB. Use dependency injection.
Instead of
#ServerEndpoint(value = "/websocket/{room-name}/{nick-name}", encoders = { ChatMessageEncoder.class }, decoders = { ChatMessageDecoder.class })
public class ChatEndPoint {
// traitement de la connexion d'un client
#OnOpen
public void open(Session session, EndpointConfig conf, #PathParam("room-name") String roomName, #PathParam("nick-name") String nickName) throws Exception {
System.out.println("connection ouverte");
session.getUserProperties().put("salle", roomName);
DAO dao=new DAO();
dao.createConnection(nickName, roomName);
use
#ServerEndpoint(value = "/websocket/{room-name}/{nick-name}", encoders = { ChatMessageEncoder.class }, decoders = { ChatMessageDecoder.class })
public class ChatEndPoint {
#Inject
private DAO dao;
// traitement de la connexion d'un client
#OnOpen
public void open(Session session, EndpointConfig conf, #PathParam("room-name") String roomName, #PathParam("nick-name") String nickName) throws Exception {
System.out.println("connection ouverte");
session.getUserProperties().put("salle", roomName);
dao.createConnection(nickName, roomName);

Categories

Resources