Wednesday October 31, 2007
TOTD #15: Delete/Update Row from Database using jMaki Data Table
A Previous Entry explained how a Data Table widget can be populated from a database using Java Persistence API (JPA). This TOTD extends that entry and explains how a selected row from the Data Table can be deleted from the database. This entry is created based upon a requirement from Dave Briccetti at Silicon Valley Code Camp 2007 last weekend.
The first part of the entry is also a re-write of using NetBeans 6 and the latest jMaki NetBeans plugin.
Web Application'
project and name it as 'jmaki-database'.
Next' button, add 'jMaki Ajax Framework'
and choose 'Standard' layout as shown below:
Finish' button.Runtime' tab, expand Databases, connect
to the default database (with the URL 'jdbc:derby://localhost:1527/sample
[app on APP]'). Specify the username 'app' and password
'app'.Execute Command...'
and issue the command:create table BOOKS (title varchar(255),
author varchar(255),
isbn varchar(255),
description varchar(255),
PRIMARY KEY (isbn))INSERT INTO BOOKS VALUES('Galloway Book of Running', 'Jeff Galloway',
'ABC001', 'The best book on running');
INSERT INTO BOOKS VALUES('The Complete Book of Running', 'James Fixx',
'ABC002', 'Oldest book of running');
INSERT INTO BOOKS VALUES('The Runners Handbook', 'Bob Glover', 'ABC003',
'Bestselling Guide for Beginning and Intermediate Runners');
INSERT INTO BOOKS VALUES('Daniel Running Formula', 'Jack Tupper Daniels',
'ABC004', 'Proven programs 800m to Marathon');
INSERT INTO BOOKS VALUES('Chi Running', 'Danny Drever', 'ABC005',
'Revolutionary approach to effortless, injury-free running');
INSERT INTO BOOKS VALUES('Running for Mortals', 'John Bingham', 'ABC006', 'A
common sense plan for changing your life through running');
INSERT INTO BOOKS VALUES('Marathoning for Mortals', 'John Bingham',
'ABC007', 'Regular person guide to marathon');
INSERT INTO BOOKS VALUES('Marathon', 'Hal Higdon', 'ABC008', 'The Ultimate
Training Guide');jmaki-database',
right-click and select 'New' and choose 'Entity
Classes From Database...'.jdbc/sample' as 'Data Source'.BOOKS' in 'Available Tables' and
click on 'Add' and enter the values as shown below:
Next'.server' as shown below:
Create Persistence Unit...' to create the
persistence unit and enter the values as shown below:
Create'.and click on 'Finish'.
@NamedQuery(name = "Books.findAll", query = "SELECT b FROM Books b")Configuration Files' and open
'persistence.xml'.Add Class' button and choose 'server.Books'
class and click 'OK'. This will ensure that the generated
entity class is explicitly recognized by the EntityManagerFactory.Web Pages', select 'New'
and then 'JSP...'. Give the name as 'data' as
shown:
Finish'.data.jsp' with the
following:<%@ page import="java.util.*" %>
<%@ page import="server.Books" %>
<%@ page import="javax.persistence.*" %>
<%
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("jmaki-databasePU");
EntityManager em = emf.createEntityManager();
List<Books> list = em.createNamedQuery("Books.findAll").getResultList();
out.println("{columns : [" +
"{ label : 'Title', id : 'title'}," +
"{ label :'Author', id : 'author'}," +
"{ label :'ISBN', id : 'isbn'}," +
"{ label :'Description', id : 'description'}" +
"],");
out.println("rows: [");
for (int i=0; i<list.size(); i++) {
Books b = list.get(i);
out.print("{ id: '" + b.getIsbn() + "', " +
"title: '" + b.getTitle() + "'," +
"author: '" + b.getAuthor() + "'," +
"isbn: '" + b.getIsbn() + "'," +
"description: '" + b.getDescription()
+ "'}");
if (i < list.size()-1)
out.println(",");
else
out.println();
}
out.println("] }");
%>index.jsp', drag-and-drop a 'Yahoo Data Table' widget from the jMaki Palette in the 'Main
Content Area'.<a:widget name="yahoo.dataTable"
value="{columns :
[
{ label : 'Title', id : 'title'},
{ label :'Author', id : 'author'},
{ label : 'ISBN', id : 'isbn'},
{ label : 'Description', id : 'description'}
],
rows :
[
{ title : 'Book Title 1', author : 'Author 1', isbn: '4412', description
: 'A Some long description'},
{ id : 'bar', title : 'Book Title 2', author : 'Author 2', isbn :
'4412', description : 'A Some long description'}
]
}" />
<a:widget name="yahoo.dataTable" service="data.jsp" />
The 'service' attribute tells jMaki runtime to retrieve the data
for DataTable widget from 'data.jsp' instead of the using static
data.
Source Packages', 'server',
edit 'Books.java' and add the following NamedQuery:@NamedQuery(name = "Books.deleteByIsbn", query = "DELETE FROM Books b
WHERE b.isbn = :isbn")Web Pages', select 'New'
and then 'JSP...'. Give the name as shown:
Finish'.delete.jsp' with the
following:<%@ page import="javax.persistence.*" %>
<%
String isbn = request.getParameter("isbn");
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("jmaki-databasePU");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.createNamedQuery("Books.deleteByIsbn").
setParameter("isbn", isbn).
executeUpdate();
em.getTransaction().commit();
%>Web pages' and edit 'glue.js' to add
the following fragment in '*onSelect' subscribe method:jmaki.doAjax({method: "POST",
url: "delete.jsp?isbn=" + encodeURIComponent(args.value.isbn),
callback: function(_req) {
jmaki.publish('/jmaki/table/removeRow', { targetId:
args.value.isbn });
}
});index.jsp' as:<a:widget name="yahoo.dataTable" service="data.jsp" subscribe="/jmaki/table"/>That's it! Now clicking on any row of the table will delete that particular row from the database and also from the table. If jMaki Debugger Console is enabled, then the messages are shown as below:

Using the similar steps described in bullet #9-13, a row can be updated in the database.
Please leave suggestions on other TOTD that you'd like to see. A complete archive is available here.
Technorati: totd jmaki glassfish netbeans jpa database
Posted by Arun Gupta in web2.0 | Comments[41]
|
|
|
|
Today's Page Hits: 3997
Hi Arun,
The example code you have shown here is quite interesting but i am receiving an error like this "Failed to load data: doAjax error communicating with CustomerData.jsp. Server returned status code 500."
I have performed your sample codes above onto the customer table available in derby default tables. When i examined the fault using firebug i got the following error:
</head><body><h1>HTTP Status
500 - </h1><hr/><p><b>type</b> Exception report</p><p><b>message</b></p><p><b>description</b>The server
encountered an internal error () that prevented it from fulfilling this request.</p><p><b>exception
</b> <pre>org.apache.jasper.JasperException: javax.persistence.PersistenceException: No Persistence provider
for EntityManager named WebApplication3PU: Provider named oracle.toplink.essentials.PersistenceProvider
threw unexpected exception at create EntityManagerFactory:
javax.persistence.PersistenceException
javax.persistence.PersistenceException: Exception [TOPLINK-28018] (Oracle TopLink Essentials - 2.0 (Build
b58g-fcs (09/07/2007))): oracle.toplink.essentials.exceptions.EntityManagerSetupException
Exception Description: predeploy for PersistenceUnit [WebApplication3PU] failed.
Internal Exception: javax.persistence.PersistenceException: Exception [TOPLINK-28010] (Oracle TopLink
Essentials - 2.0 (Build b58g-fcs (09/07/2007))): oracle.toplink.essentials.exceptions.EntityManager
SetupException
Exception Description: PersistenceUnitInfo WebApplication3PU has transactionType JTA, but doesnt have
jtaDataSource.
at oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl
.java:643)
at oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider.createEntityManagerFactory(EntityManagerFactoryProvider
.java:196)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:110)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:83)
at org.apache.jsp.CustomerData_jsp._jspService(CustomerData_jsp.java from :54)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:93)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:831)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:373)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:470)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:364)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:831)
at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:411)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:317
)
....
....
I couldnot make out where the error could be...
Posted by Manoj on October 31, 2007 at 07:41 AM PDT #
Seems like your persistence unit is not properly configured. Can you try verifying your persistence unit for a simple application as described at: http://blogs.sun.com/arungupta/entry/hello_jpa_world
Posted by Arun Gupta on November 01, 2007 at 02:31 AM PDT #
Hi, the value does not remove from database and the delete.jsp is empty. Is it my fault? best regards Anja
Posted by Anja on November 02, 2007 at 08:35 AM PDT #
I'm having the same problem with the delete. It looks like the doAjax call was not being executed, but I think the real problem is that the onSelect is not getting the message from the dataTable.
glue.js : onSelect request from: undefined value=undefined
Also step 8 says 'Dojo Editable Table' but the widget added is a from yahoo:
a:widget name="yahoo.dataTable"
Posted by Charles Anderson on November 02, 2007 at 11:16 AM PDT #
I changed from a yahoo table to a dojo table and it works.
Right now I have
<div id="content" style="height:400px">
<a:widget name="yahoo.dataTable" service="data.jsp" subscribe="/jmaki/table"/>
<a:widget name="dojo.table" service="data.jsp" subscribe="/jmaki/table"/>
</div>
If I click on the dojo table everything works, the row is removed from both tables. If I click on the yahoo table, I see this:
Publish Match : : Topic: /yahoo/dataTable/onSelect listener {topic : '*onSelect' , target : {functionHandler : function (args) { jmaki.doAjax({method:"POST", url:"delete.jsp?isbn=" + encodeURIComponent(args.value.isbn), callback:function (req) {jmaki.publish("/jmaki/table/removeRow", {targetId:args.value.isbn});}}); jmaki.log("glue.js : onSelect request from: " + args.id + " value=" + args.value); }} , action : 'call' , id : 'jmk_2'}
in the jMaki logger, but nothing is executed. Click on dojo table, same log entry, but then
glue.js : onSelect request from: undefined value=[object Object]
Publish : Topic: /jmaki/table/removeRow message {targetId : 'ABC008'}
when they are executed.
Posted by Charles Anderson on November 02, 2007 at 03:01 PM PDT #
Hi, it doesn't work with a dojo.table too.
Posted by Anja on November 02, 2007 at 05:02 PM PDT #
I fixed the typo in Step 8. I tried the exact same sample with Dojo Data Table and it worked for me. Can you confirm you are using the latest plugin as opposed to 1.0 ? Where are you downloading it from ?
-Arun
Posted by Arun Gupta on November 04, 2007 at 04:11 PM PST #
Hi, sorry it was my fault, it works. I've put the expression in the glue.js not in onSelect.
Thank you, it works now.
Have I put an insert clause for the insert in the Books.java and how looks it like.
Posted by Anja on November 05, 2007 at 06:42 AM PST #
Hi Arun,
I tried to follow the steps as ooutlined. I am running NB6Beta2 with JDK1.6 (bundled with it). I have a class mis match for Books.class. Can you please help me to resolve this?
[javac] C:/Program Files/glassfish-v2-b53/domains/domain1/generated/jsp/j2ee-modules/jmaki-database
/org/apache/jsp/data_jsp.java:7: cannot access server.Books
PWC6199: Generated servlet error:
[javac] bad class file: C:\Documents and Settings\rkayamboo\Desktop\jmaki-database\build\web\WEB-INF
\classes\server\Books.class
[javac] class file has wrong version 50.0, should be 49.0
[javac] Please remove or make sure it appears in the correct subdirectory of the classpath.
[javac] import server.Books;
[javac] ^
[javac] 1 error
Posted by Sekar on November 05, 2007 at 12:02 PM PST #
Seems like the class file is compiled with Java SE 6 and GlassFish is using Java SE 5. Can you please check ?
Posted by Arun Gupta on November 05, 2007 at 12:33 PM PST #
Arun,
I was able to get past that. The issue was with the GF server on NB6. Though I installed the GFV58b bundled with NB6, the server was pointing to GFV53 (bundled with NB5.5). I think this happened when I imported the settings from NB5.5. Thank you so much Arun for the tutorial and your response.
Sekar.
Posted by Sekar on November 05, 2007 at 01:04 PM PST #
I'm using JMaki 1.6.11 that came with netbeans 6 beta 2. I show no updates for it in the plugins, so I downloaded the latest from the link before step 1, and it was the same 1.6.11. Still doesn't work with the yahoo dataTable, just dojo.
Posted by Charles Anderson on November 06, 2007 at 08:16 AM PST #
Sorry about the trouble. I'll create a screencast showing these steps and hopefully that will clarify the steps.
Posted by Arun Gupta on November 06, 2007 at 05:50 PM PST #
Posted by Arun Gupta's Blog on November 08, 2007 at 07:25 AM PST #
Charles, the screencast is now available at: http://blogs.sun.com/arungupta/entry/screencast_web10_crud_using_jmaki
Posted by Arun Gupta on November 08, 2007 at 08:07 AM PST #
I get the same result as Charles. Yahoo table does not respond, dojo table works as demonstrated. I'm using Netbeans 6.0 Beta 1 and jmaki plugin 1.6.11
Posted by Jonathan Wilcox on November 13, 2007 at 10:54 AM PST #
Did you follow the screencast at:
http://blogs.sun.com/arungupta/entry/screencast_web10_crud_using_jmaki
?
Posted by Arun Gupta on November 13, 2007 at 11:26 AM PST #
Hi Arun,
great example! The delete section works but I had to substitute in glue.js args.value.isbn with args.targetId; probably you understand why ... Thank you very much, Raffaele.
P.S. Every other sample on database management (add rows, filter rows, display tooltips etc.) will be very appreciated!
Posted by Raffaele Favilli on November 18, 2007 at 11:42 PM PST #
Hi Arun, I am a beginner and tried to implement your example using tomcat rather than glassfish. When I create the persistence unit I do not have the javax.persistence library so it wont compile. Is this because I must use glassfish or can I include the library from somewhere.
Thanks in advance!
Posted by Stephen Howells on November 25, 2007 at 11:49 AM PST #
A stand-alone persistence library can also be downloaded from https://glassfish.dev.java.net/downloads/persistence/JavaPersistence.html. The Persistence library used in GlassFish v2 final build is linked from:
http://download.java.net/javaee5/v2_branch/promoted/shared/glassfish-persistence/glassfish-persistence-installer-v2-b58g.jar
Posted by Arun Gupta on November 25, 2007 at 11:54 AM PST #
Arun, many thanks again for your replies. I did as you suggested but despite adding the jar file to the Netbeans project libraries the generated class file fails to compile due to non recognition of all the lines that start
@Entity
@NamedQueries
@Table
@Column
It says it can't find each symbol. I presume that means the compiler still cannot use the library.
I have added the line
import javax.persistence.*;
Any hints? Sorry in advance for the dumb questions.
Steve
Posted by Stephen Howells on November 27, 2007 at 11:16 AM PST #
Thank you for your good example, but it doesn't work for an insert into a database.
Have you an example for an insert new rows from an data.table into a database, please?
Posted by Anja on January 02, 2008 at 11:39 AM PST #
Stephen, I added toplink-essentials.jar and toplink-essentials-agent.jar from the standalone GlassFish Persistence installer in my web application and could compile the classes fine. I tried on Tomcat 6.0.13. And make sure you click on "Add JAR/Folder" in Libraries tab.
Posted by Arun Gupta on January 02, 2008 at 04:50 PM PST #
Anja, For insert, you'll need to add a HTML form with a text box, read the value from the box and then pass it on to insert.jsp. Have you tried this and it did not work ?
-Arun
Posted by Arun Gupta on January 02, 2008 at 04:52 PM PST #
please can you give me a little example for these problem, it doesn't work. thank you so much
Posted by Anja on January 03, 2008 at 10:05 AM PST #
nothing showing up from data.jsp
regards, i
Posted by Ingemar on January 04, 2008 at 05:30 PM PST #
Ingemar, do you see any errors in the GlassFish console ?
Posted by Arun Gupta on January 04, 2008 at 05:43 PM PST #
Hello Arun,
Thanks for the swift reply to my short comment.
Can give you my environment first:
glassfish-v2-b58g (standalone, not bundled with netbeans).
Java version "1.6.0_03" ( did upgrade from jdk1.5.0_12 , thought that might help me out ).
Running latest Netbeans ( NetBeans IDE 6.0 (Build 200711261600) ).
Using ajax Jmakik support 1.6.13.
The glassfish console ends with the following:
SMGT0007: Self Management Rules service is enabled
Application server startup complete.
deployed with moduleid = Svemab
[TopLink Info]: 2008.01.05 02:25:19.705--ServerSession(28732011)--TopLink, version: Oracle TopLink Essentials - 2.0 (Build b58g-fcs (09/07/2007))
[TopLink Info]: 2008.01.05 02:25:22.004--ServerSession(28732011)--file:/C:/Users/ing/Documents/NetBeansProjects/Svemab/build/web/WEB-INF/classes/-SvemabPU login successful
- so I hade to add the following in my persistence.xml
'<provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider>'
At first I thought the the index.jsp did not find the data.jsp - but it is probably, because it complained at first at my faulty written @NamedQuery - now it is not complaing about that.
my index.jsp has the follwoing:
<div id="content" style="height:400px">
<a:widget name="yahoo.dataTable" service="data.jsp" subscribe="/jmaki/table"/>
<a:widget name="dojo.table" service="data.jsp" subscribe="/jmaki/table"/>
</div>
but it is not showing anything from my data.jsp.
Hope that you can give me a hand.
regards, Ingemar
regards, i
Posted by Ingemar on January 05, 2008 at 06:42 AM PST #
Hello arun,
Can you see what my trouble is?
regards, i
ps.
eager to get started
Posted by ingmar on January 08, 2008 at 07:23 AM PST #
Posted by Arun Gupta's Blog on January 24, 2008 at 04:46 AM PST #
Posted by Arun Gupta's Blog on January 24, 2008 at 05:53 AM PST #
Hello Arun.
Do not understand your latest 'trackback'.
Did you have some kind of answer for me ?
regards, i
Posted by ingemar on January 25, 2008 at 12:23 AM PST #
I am loading a jmaki combobox from the database here is the code for the page:
<%
EntityManagerFactory emf = Persistence.createEntityManagerFactory("wprjSonicWebMonitorPU");
EntityManager em = emf.createEntityManager();
List<Sonicinfo> list = em.createNamedQuery("server.getProfiles").getResultList();
out.println("{value : [" +
"{ label : 'profile', value : 'id'}" + "]");
for (int i = 0; i < list.size(); i++)
{
Sonicinfo b = list.get(i);
out.print("{ id: '" + b.getEventid() + "'" + "' - '" + "'" + "profile: '" + b.getConnectionname() + "'}");
}
out.println("] }");
%>
For some reason I can't seem to populate the combobox?
Thanks
Posted by David Costelloe on January 30, 2008 at 08:27 AM PST #
Hi David Costelloe-
your JSON Array isn't correct
<%
EntityManagerFactory emf = Persistence.createEntityManagerFactory("buchportalPU");
EntityManager em = emf.createEntityManager();
List<Bestseller> list = em.createNamedQuery("Bestseller.findAll").getResultList();
out.println("value= [");
for (int i=0; i<list.size(); i++) {
Bestseller b = list.get(i);
out.print("{label : '" + b.getAutor() + "'" + "," + " value : '" + b.getTitel() + "'}");
if (i < list.size()-1)
out.println(",");
}
out.println("]");
%>
Try this - it works.
best regards Anja
Posted by Anja on February 01, 2008 at 03:09 PM PST #
I am triing to update the table from information I get from a form with 3 parameters.
I can't seem to make the table update after the query. In firebug I can see that the information is retrieved from the database:
{columns : [{ label : 'Consumo PVB ID', id : 'conspvbid'},{ label :'Cliente', id : 'cliente'},{ label
:'Produção ID', id : 'producaoid'},{ label :'Tipo PVB', id : 'tipopvb'},{ label :'Quantidade(m2)', id
: 'quantidade'},{ label :'Data', id : 'datacorte'},{ label :'Tipo PVB ID', id : 'tipopvbid'},{ label
:'Rolo PVB ID', id : 'chapaid'}],
rows: [
{ conspvbid: '1',cliente: 'VIMARTINS - SOCIEDADE TRANSFORMADORA DE VIDRO, LDA',producaoid: '2007110001'
,tipopvb: '0,38 Translucido',quantidade: '35',datacorte: '2007-12-27',tipopvbid: '1',chapaid: '1'}
] }
However, the table doesn't update. I think it is partially because the form has the return false statement:
<form method="POST" onSubmit="doAjaxSubmit();return false;" action='conspvbclientetipodata.jsp' >
If i take off the return false it doesnt work.
The doAjaxSubmit() method is:
function doAjaxSubmit() {
var selectedCliente = jmaki.getWidget('clienteac').getValue();
var selectedTipoPVB = jmaki.getWidget('tipopvbac').getValue();
var selectedDataInicio = jmaki.getWidget('datainicio').getValue();
var selectedDataFim = jmaki.getWidget('datafim').getValue();
jmaki.log("Cliente:" + selectedCliente);
jmaki.log("Tipo PVB:" + selectedTipoPVB);
jmaki.log("Data Inicio:" + selectedDataInicio);
jmaki.log("Data Fim:" + selectedDataFim);
// now post this form data
jmaki.doAjax({ url : "dataconspvbclientetipodata.jsp",
method : 'POST',
content : { cliente : selectedCliente,
tipopvb : selectedTipoPVB,
datainicio : selectedDataInicio,
datafim : selectedDataFim},
callback: function(_req) {
jmaki.publish('/jmaki/table/updateRow', { targetId: "bar" });
}
});
}
Can I get any help on this. How can I make the page reload after the query.
Posted by Miguel Pereira on February 12, 2008 at 02:51 PM PST #
jjj
Posted by 81.95.160.41 on April 13, 2008 at 10:52 PM PDT #
I'm with Anja, how do you reload a dataTable from glue?
Posted by Jonathan Maher on April 18, 2008 at 01:32 AM PDT #
hi, please help me , when i choice new row and parameter isbn passed , i want to go other page - in other words , when click the row goto other page . thanks.
Posted by yadi on April 18, 2008 at 05:53 AM PDT #
Hi,
sometimes you have to clear the table - cache for visiting the new data in the table. So you have to put this in your persistence.xml :
<properties>
<property name="toplink.cache.shared.tablename1" value="false"/>
<property name="toplink.cache.shared.tablename2" value="false"/> ....
</properties>
Please can you post you glue.js for the table an specify your question?
Posted by Anja on April 18, 2008 at 11:49 AM PDT #
the last comment is for Jonathan Maher
Posted by Anja on April 18, 2008 at 11:50 AM PDT #
Thanks Anja, I just thought there was a simple Javascript or jMaki call that reloaded a dataTable if the service attribute value was a jsp page which returned columns and rows of JSON. I removed the service attribute/value and added the columns to the value attribute and returned the JSON rows via a bean. I can now clear and add rows as follows:
jmaki.publish("/yahoo/dataTable/master/clear", { });
jmaki.publish("/yahoo/dataTable/master/addRows", {value : objData });
Posted by Jonathan on April 22, 2008 at 05:58 AM PDT #