Forgive me for not including something, I'm new here. here is the console info
java.lang.IllegalStateException:
Exception Description: No transaction is currently active
org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.rollback(EntityTransactionImpl.java:176)
music.data.ProductDB.insertProduct(ProductDB.java:73)
music.admin.ProductAdminController.updateProduct(ProductAdminController.java:123)
music.admin.ProductAdminController.doGet(ProductAdminController.java:37)
music.admin.ProductAdminController.doPost(ProductAdminController.java:50)
javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
If you look at the above image, you see that right before the call to commit(); the transaction is verymuch so active. the rest of the files that are involved are here:
ProductDB.java (Database managing class)
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package music.data;
import java.util.List;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.NoResultException;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
import music.business.Product;
/**
*
* @author Harley
*/
public class ProductDB {
public static List<Product> selectProducts() {
List<Product> products;
DBUtil util = new DBUtil();
EntityManager em = util.getEmFactory().createEntityManager();
String JPQL = "SELECT p FROM Product p";
TypedQuery<Product> q = em.createQuery(JPQL, Product.class);
products = q.getResultList();
if (products.isEmpty()) {
products = null;
}
em.close();
return products;
}
public static Product selectProduct(String productCode) {
DBUtil u = new DBUtil();
EntityManager em = u.getEmFactory().createEntityManager();
String JPQL = "Select p from Product p "
+ "where p.code = :code";
TypedQuery<Product> q = em.createQuery(JPQL, Product.class);
q.setParameter("code", productCode);
try {
Product p = q.getSingleResult();
return p;
} catch (NoResultException e) {
return null;
} finally {
em.close();
}
}
public static boolean exists(String productCode) {
Product p = selectProduct(productCode);
if (p != null) {
return true;
} else {
return false;
}
}
public static void insertProduct(Product p) {
DBUtil u = new DBUtil();
EntityManager em = u.getEmFactory().createEntityManager();
EntityTransaction trans = em.getTransaction();
trans.begin();
try {
em.persist(p);
trans.commit();
} catch (Exception e) {
System.out.println(e);
trans.rollback();
} finally {
em.close();
}
}
public static void updateProduct(Product p) {
DBUtil u = new DBUtil();
EntityManager em = u.getEmFactory().createEntityManager();
EntityTransaction trans = em.getTransaction();
trans.begin();
try {
em.merge(p);
trans.commit();
} catch (Exception e) {
System.out.println(e);
trans.rollback();
} finally {
em.close();
}
}
public static void deleteProduct(Product p) {
DBUtil u = new DBUtil();
EntityManager em = u.getEmFactory().createEntityManager();
EntityTransaction trans = em.getTransaction();
trans.begin();
try {
em.remove(em.merge(p));
trans.commit();
} catch (Exception e) {
System.out.println(e);
trans.rollback();
} finally {
em.close();
}
}
private static class DBUtil {
private final EntityManagerFactory emf;
public DBUtil() {
emf = Persistence.createEntityManagerFactory("productMaintenancePU");
}
public EntityManagerFactory getEmFactory() {
return emf;
}
}
}
The jsp file that i use to add/update entries is here:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@include file="includes/header.jsp" %>
<h1>Product</h1>
<form method="post" action="">
<c:choose>
<c:when test="${product != null}">
<label>Code:</label>
<input name="productCode" class="smallText" type="text" value=
<c:out value="${product.getCode()}"/>><br/>
<label>Description:</label>
<input name="description" class="bigText" type="text" value="${product.getDescription()}"><br/>
<label>Price:</label>
<input name="price" class="smallText" type="text" value=
<c:out value="${product.getPrice()}"/>><br/>
</c:when>
<c:otherwise>
<label>Code:</label>
<input name="productCode" class="smallText" type="text"/><br/>
<label>Description:</label>
<input name="description" class="bigText" type="text"/><br/>
<label>Price:</label>
<input name="price" class="smallText" type="text"/><br/>
</c:otherwise>
</c:choose>
<label> </label>
<button type="submit" name="action" value="updateProduct">Submit</button>
</form>
</body>
</html>
Persistance.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="productMaintenancePU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/music_jpa?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="sesame"/>
<property name="javax.persistence.schema-generation.database.action" value="create"/>
</properties>
</persistence-unit>
</persistence>
The Servlet
package music.admin;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import music.business.Product;
import music.data.ProductDB;
public class ProductAdminController extends HttpServlet {
/* Comment this method out when using this class with a database
* instead of a text file.
*/
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// get current action
String action = request.getParameter("action");
if (action == null) {
action = "displayProducts"; // default action
}
// perform action and set URL to appropriate page
String url = "/index.jsp";
if (action.equals("displayProduct")) {
url = displayProduct(request, response);
} else if (action.equals("addProduct")) {
url = "/product.jsp";
} else if (action.equals("deleteProduct")) {
url = deleteProduct(request, response);
} else if (action.equals("updateProduct")) {
url = updateProduct(request, response);
} else {
url = displayProducts(request, response);
}
getServletContext()
.getRequestDispatcher(url)
.forward(request, response);
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
private String displayProducts(HttpServletRequest request,
HttpServletResponse response) {
List<Product> products = ProductDB.selectProducts();
request.setAttribute("products", products);
return "/products.jsp";
}
private String displayProduct(HttpServletRequest request,
HttpServletResponse response) {
String productCode = request.getParameter("productCode");
Product product;
if (productCode == null || productCode.isEmpty()) {
product = new Product();
} else {
product = ProductDB.selectProduct(productCode);
}
request.setAttribute("product", product);
return "/product.jsp";
}
private String addProduct(HttpServletRequest request,
HttpServletResponse response) {
return "/product.jsp";
}
private String updateProduct(HttpServletRequest request,
HttpServletResponse response) {
String productCode = (String) request.getParameter("productCode");
String description = (String) request.getParameter("description");
String priceString = (String) request.getParameter("price");
double price;
try {
price = Double.parseDouble(priceString);
} catch (NumberFormatException e) {
price = 0;
}
Product product = (Product) request.getAttribute("product");
if (product == null) {
product = new Product();
}
product.setCode(productCode);
product.setDescription(description);
product.setPrice(price);
request.setAttribute("product", product);
String message = "";
if (product.getPrice() <= 0) {
message = "You must enter a positive number for the price without "
+ "any currency symbols.";
}
if (product.getDescription().length() == 0) {
message = "You must enter a description for the product.";
}
if (product.getCode().length() == 0) {
message = "You must enter a code for the product.";
}
request.setAttribute("message", message);
String url;
if (message.isEmpty()) {
if (ProductDB.selectProduct(product.getCode()) != null) {
ProductDB.updateProduct(product);
} else {
ProductDB.insertProduct(product);
}
url = displayProducts(request, response);
} else {
url = "/product.jsp";
}
return url;
}
private String deleteProduct(HttpServletRequest request,
HttpServletResponse response) {
String productCode = request.getParameter("productCode");
Product product = ProductDB.selectProduct(productCode);
request.setAttribute("product", product);
String url;
String yesButton = request.getParameter("yesButton");
if (yesButton != null) {
ProductDB.deleteProduct(product);
url = displayProducts(request, response);
} else {
url = "/confirm_product_delete.jsp";
}
return url;
}
}
JPA Entity: product
package music.business;
import java.text.NumberFormat;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Product implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private String code;
private String description;
private double price;
public Product() {
code = "";
description = "";
price = 0;
}
public void setCode(String code) {
this.code = code;
}
public String getCode() {
return code;
}
public void setDescription(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public void setPrice(double price) {
this.price = price;
}
public double getPrice() {
return price;
}
public String getPriceNumberFormat() {
NumberFormat number = NumberFormat.getNumberInstance();
number.setMinimumFractionDigits(2);
if (price == 0) {
return "";
} else {
return number.format(price);
}
}
public String getPriceCurrencyFormat() {
NumberFormat currency = NumberFormat.getCurrencyInstance();
return currency.format(price);
}
}
products.jsp(displays all entries)
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@include file="includes/header.jsp" %>
<h1>Products</h1>
<table>
<col width='80'><col width='500'><col width='80'><col width='50'><col width='100'>
<tr>
<th class="alignl">Code</th>
<th>Description</th>
<th class="alignr">Price</th>
<th></th>
<th></th>
</tr>
<c:forEach var="item" items="${products}">
<tr>
<form method="post" action="">
<td><input name="productCode" hidden type="text" value="${item.getCode()}"/>${item.getCode()}</td>
<td>${item.getDescription()}</td>
<td class="alignr">${item.getPriceCurrencyFormat()}</td>
<td><button name="action" value="displayProduct" type="submit">Edit</button></td>
<td><button name = "action" value="deleteProduct" type="submit">Delete</button></td>
</form>
</tr>
</c:forEach>
</table>
<form method="post" action="ProductMaint3">
<button type="submit" name="action" value="addProduct">Add Product</button>
</form>
</body>
</html>
Functionally, the only issue occurs when i try to insert a new entry into the database... delete and update work. pls let me know if you need any more information.
答案 0 :(得分:0)
产品表中有一个名为PRODUCTID的附加列。这是主键和外键。我还是sql的新手,所以我不知道如何处理或使用外键...此外,此列不需要允许程序工作。这张桌子是由我的导师给我的......所以我必须和她说话。答:删除列PRODUCTID,我不再收到错误。效果很好。