I have a working ORM and been able to map objects to my database. So its up an running.
I've created a web service that looks like this:
#Stateless
#Path("user")
#LocalBean
public class userFacade {
#PersistenceContext(unitName = "Fakebook3")
private EntityManager em;
public userFacade() {
// TODO Auto-generated constructor stub
}
public void persistUser(User user){
em.persist(user);
}
#GET
#Path("edit")
#Produces(MediaType.APPLICATION_JSON)
public Response editUserInformation(
#QueryParam("userid") int userid,
#QueryParam("jobbText") String jobbText,
#QueryParam("intresseText") String intresseText,
#QueryParam("bostadText") String bostadText
){
String jobbTextEscaped = StringEscapeUtils.escapeHtml3(jobbText);
String intresseTextEscaString = StringEscapeUtils.escapeHtml3(intresseText);
String bostadTextEscaped = StringEscapeUtils.escapeHtml3(bostadText);
String sql = "UPDATE user SET job=?, interest=?, bostad=? WHERE id="+userid;
Query query = em.createQuery(sql);
query.setParameter(1, jobbTextEscaped);
query.setParameter(2, intresseTextEscaString);
query.setParameter(3, bostadTextEscaped);
query.executeUpdate();
return Response.status(200).entity("This is a callback message. Handle it!").build();
}
}
I'm using eclipse web service tool and input the paramater values and get this error:
13:23:41,184 ERROR [org.jboss.as.ejb3.invocation] (default task-4) JBAS014134: EJB Invocation failed on component userFacade for method public javax.ws.rs.core.Response se.chas.fakebook.facade.userFacade.editUserInformation(int,java.lang.String,java.lang.String,java.lang.String): javax.ejb.EJBException: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: fakebook.user is not mapped [UPDATE fakebook.user SET user.job=?, user.interests=?, user.bostad=? WHERE id=1]
at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleExceptionInOurTx(CMTTxInterceptor.java:190) [wildfly-ejb3-8.1.0.Final.jar:8.1.0.Final]
at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:275) [wildfly-ejb3-8.1.0.Final.jar:8.1.0.Final]
and so on. I tried to create to map the entities using eclipse and placed them in the same folder as the entities.
But I'm still getting same exception. I also tried changing the sql statement from "... facebook.user ..." to only use "... user ..."
What am I doing wrong?
I can't upload images here so here comes a link with a project tree: http://imgur.com/4yemPZH
Your query should be like this:
String sql = "UPDATE User SET job=?, interest=?, bostad=? WHERE id="+userid;
Try this :
UPDATE user SET job=:job, interest=:interest, bostad=:bostad WHERE id="+userid
query.setParameter("job", jobbTextEscaped);
query.setParameter("interest", intresseTextEscaString);
query.setParameter("bostad ", bostadTextEscaped);
Related
I am trying to create a remote service containing JPQL but I am getting this error for the simplest query.
In my authentication service:
#Override
public Users checkDatabase(String email) {
Query query = entityManager.createQuery("SELECT u from Users u WHERE u.nom = :email", Users.class)
.setParameter("email", email);
Users user = (Users) query.getSingleResult();
return user;
}
and my client code looks like:
String jndiName = "Petroca-ear/Petroca-ejb/AuthenticationServices!com.esprit.services.AuthenticationServicesRemote";
Context context = new InitialContext();
AuthenticationServicesRemote proxy = (AuthenticationServicesRemote) context.lookup(jndiName);
System.out.println(proxy.checkEmail("test#s"));
Users user = (Users) proxy.checkDatabase("peter");
while executing this, I am getting this error:
false
Exception in thread "main" java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.String
at org.jboss.ejb.client.remoting.ProtocolMessageHandler.readAttachments(ProtocolMessageHandler.java:55)
at org.jboss.ejb.client.remoting.InvocationExceptionResponseHandler$MethodInvocationExceptionResultProducer.getResult(InvocationExceptionResponseHandler.java:82)
at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:276)
at org.jboss.ejb.client.EJBObjectInterceptor.handleInvocationResult(EJBObjectInterceptor.java:64)
at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:290)
at org.jboss.ejb.client.EJBHomeInterceptor.handleInvocationResult(EJBHomeInterceptor.java:88)
at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:290)
at org.jboss.ejb.client.TransactionInterceptor.handleInvocationResult(TransactionInterceptor.java:46)
at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:290)
at org.jboss.ejb.client.ReceiverInterceptor.handleInvocationResult(ReceiverInterceptor.java:129)
at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:265)
at org.jboss.ejb.client.EJBClientInvocationContext.awaitResponse(EJBClientInvocationContext.java:453)
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:202)
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:181)
at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:144)
at com.sun.proxy.$Proxy2.checkDatabase(Unknown Source)
at TEST.testPetroca.main(testPetroca.java:23)
I have following method,
public Project getProjectByUser(long userId)
throws IOException {
SqlSession sqlSession = null;
Project response = null;
Map<String, Long> projectParam = new HashMap<String, Long>();
projectParam.put("userId", userId);
try {
sqlSession = DBSessionManager.getInstance().getSessionFactory()
.openSession();
LOG.debug("SqlSession opened for Project mapper");
ProjectMapper projectMapper = sqlSession
.getMapper(ProjectMapper.class);
sqlSession.insert("getProjectByUserId", projectParam);
sqlSession.commit();
response = projectMapper.getProjectByUserId(userId);
} finally {
if (sqlSession != null) {
sqlSession.close();
LOG.debug("SqlSession closed");
} else {
System.out.println("_sql session null");
}
}
return response;
}
And in xml file i have the following code.
<select id="getProjectByUserId" resultMap="projectResultMap"
parameterType="map" flushCache="false" useCache="false">
SELECT
project_id,
user_id, project_name,
created_date,
last_updated_date FROM
project
WHERE
user_id=#{userId}
</select>
When I replaced (hard coded the value) the user_id=#{userId} part as user_id=1 expected result is returned. But when I pass it from client application though the value is set to the map correctly the query doesn't get it correct and results in a null return. What am I doing wrong here.
My ProjectMapper class's method definition is,
public Project getProjectByUserId(long userIdParam);
Update:
Following is the service interface method,
#GET
#Path("{userId}/{projectName}")
#Produces("application/json")
public Project getProjectByUser(#PathParam("userId") long userId);
and implementation of the above calls the data layer method (first mentioned)
Try to define your mapper like this:
public Project getProjectByUserId(#Param("userId") long userIdParam);
I'm developing a webservice using Dropwizard JDBI framework.
Now, instead of having a db configurations in yaml file, I want to use 'user specified params' what i mean to say is, the db configs will be provided through the endpoint url.
Is having custom creds possible through dropwizard jdbi?
if yes, what changes should i be thinking to do in the code while referring this ? ->
http://dropwizard.readthedocs.org/en/latest/manual/jdbi.html
I understand, in normal flow, the service method gets the config details in the run method -
-- Config Class
public class ExampleConfiguration extends Configuration {
#Valid
#NotNull
#JsonProperty
private DatabaseConfiguration database = new DatabaseConfiguration();
public DatabaseConfiguration getDatabaseConfiguration() {
return database;
}
}
-- Service Class
#Override
public void run(ExampleConfiguration config,
Environment environment) throws ClassNotFoundException {
final DBIFactory factory = new DBIFactory();
final DBI jdbi = factory.build(environment, config.getDatabaseConfiguration(), "postgresql");
final UserDAO dao = jdbi.onDemand(UserDAO.class);
environment.addResource(new UserResource(dao));
}
-- and yaml
database:
# the name of your JDBC driver
driverClass: org.postgresql.Driver
# the username
user: pg-user
# the password
password: iAMs00perSecrEET
# the JDBC URL
url: jdbc:postgresql://db.example.com/db-prod
But in this case, I might get the config details in the Resource level...
smthing like -
#GET
#Path(value = "/getProduct/{Id}/{dbUrl}/{dbUname}/{dbPass}")
#Produces(MediaType.APPLICATION_JSON)
public Product getProductById(#PathParam(value = "Id") int Id,
#PathParam(value = "dbUrl") String dbUrl,
#PathParam(value = "dbUname") String dbUname,
#PathParam(value = "dbPath") String dbPass) {
//I have to connect to the DB here! using the params i have.
return new Product(); //should return the Product
}
I'd appreciate if someone can point me a direction.
Why not just use JDBI directly?
#GET
#Path(value = "/getProduct/{Id}/{dbUrl}/{dbUname}/{dbPass}")
#Produces(MediaType.APPLICATION_JSON)
public Product getProductById(#PathParam(value = "Id") int id,
#PathParam(value = "dbUrl") String dbUrl,
#PathParam(value = "dbUname") String dbUname,
#PathParam(value = "dbPass") String dbPass) {
DataSource ds = JdbcConnectionPool.create(dbUrl, dbUname, dbPass);
DBI dbi = new DBI(ds);
ProductDAO dao = dbi.open(ProductDao.class);
Product product = dao.findById(id);
dao.close();
ds.dispose();
return product;
}
#RegisterMapper(ProductMapper.class)
static interface ProductDao {
#SqlQuery("select id from product_table where id = :id") // Whatever SQL query you need to product the product
Product findById(#Bind("id") int id);
#SqlQuery("select * from product_table")
Iterator<Product> findAllProducts();
}
static class ProductMapper implements ResultSetMapper<Product> {
public Product map(int index, ResultSet r, StatementContext ctx) throws SQLException {
return new Product(r.getInt("id")); // Whatever product constructor you need
}
}
There's a notion in the spring world of using a database router (reference: https://spring.io/blog/2007/01/23/dynamic-datasource-routing/).
You likely could setup a proxy for the database connection factory passed to DBI. That proxy would then get the credentials from a thread local (perhaps) and return the real connection giving you what you're after and still let you use the run type proxies.
Using Postgresql 8.1, Spring 3.0, Hibernate 3.6.
I have a method that calls a stored procedure that works without using Annotations, essentially it is
....
return (Integer) getJpaTemplate().execute(new JpaCallback() {
public Object doInJpa(EntityManager em) {
// Query query = em.createNamedQuery("checkZone");
Query query = em.createNativeQuery("select zoneArea from zoneArea(:pId, :zId)");
query.setParameter("pId", p.getId());
query.setParameter("zId", z.getId());
try {
return query.getSingleResult(); // Integer expected
} catch (NoResultException e) {
return 0;
}
}
});
....
How can I do this with Annotations, here's my attempt that does not work.
#NamedNativeQueries({
#NamedNativeQuery(
name = "checkZone",
query = "select zoneArea from zoneArea(:pId, :zId)",
hints = {
#QueryHint(name = "org.hibernate.callable", value = "true")
},
resultSetMapping = "scalar",
resultClass = Integer.class)})
#SqlResultSetMapping(name="scalar",columns=#ColumnResult(name="result"))
#Entity
and here is the Exception
Caused by: org.postgresql.util.PSQLException: This statement does not declare an OUT parameter. Use { ?= call ... } to declare one.
at org.postgresql.jdbc2.AbstractJdbc2Statement.registerOutParameter(AbstractJdbc2Statement.java:1849)
at org.postgresql.jdbc3.AbstractJdbc3Statement.registerOutParameter(AbstractJdbc3Statement.java:1513)
at org.hibernate.dialect.PostgreSQLDialect.registerResultSetOutParameter(PostgreSQLDialect.java:335)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1713)
at org.hibernate.loader.Loader.doQuery(Loader.java:801)
I have working code but would like to get this working with Annotations, any ideas appreciated.
I want to insert data into a table using the following code
public User registerUser(String usr, String pwd) {
u=em.find(User.class,usr);
if(u!=null)
{
return null;
}
String query1 = "insert into users values('" + usr + "','" + pwd +"')";
Query q = em.createQuery(query1);
u=em.find(User.class,usr);
return u;
}
here 'u' is the object of User class and em is EntityManager.
I get this following exception:
Servlet.service() for servlet action threw exception
org.hibernate.hql.ast.QuerySyntaxException: expecting OPEN, found 'values' near line 1, column 19 [insert into users values('pawan','am')]
Try
public User registerUser(String usr, String pwd) {
u=em.find(User.class,usr);
if(u!=null)
{
return null;
}
//Now saving...
em.getTransaction().begin();
em.persist(u); //em.merge(u); for updates
em.getTransaction().commit();
em.close();
return u;
}
If the PK is Identity, it will be set automatically in your persisted class, if you are using auto generation strategy (thanks to David Victor).
Edit to #aman_novice comment:
set it in your class
//Do this BEFORE getTransaction/persist/commit
//Set names are just a example, change it to your class setters
u.setUsr(usr);
u.setPwd(pwd);
//Now you can persist or merge it, as i said in the first example
em.getTransaction().begin();
(...)
About #David Victor, sorry I forgot about that.
You're not using SQL but JPAQL, there is no field-based insert. You persist object rather than inserting rows.
You should do something like this:
public User registerUser(String usr, String pwd) {
u=em.find(User.class,usr);
if(u!=null)
{
return u;
}
u = new User(usr, pwd);
em.persist(u);
return u;
}
This isn't really the way to go. You are trying to insert a row in a table but have no associated attached entity. If you're using the JPA entity manager - then create a new instance - set the properties & persist the entity.
E.g.
User u = new User();
u.setXXX(xx);
em.persist(u);
// em.flush() <<-- Not required, useful for seeing what is happening
// etc..
If you enable SQL loggging in Hibernate & flush the entity then you'll see what is sent to the database.
E.g. in persistence.xml:
<property name="hibernate.format_sql" value="true" />