JPA EntityTransaction Throwing java.lang.IllegalStateException

时间:2017-04-10 02:15:47

标签: java jpa insert

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)

Debug IMG

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>&nbsp;</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.

1 个答案:

答案 0 :(得分:0)

产品表中有一个名为PRODUCTID的附加列。这是主键和外键。我还是sql的新手,所以我不知道如何处理或使用外键...此外,此列不需要允许程序工作。这张桌子是由我的导师给我的......所以我必须和她说话。答:删除列PRODUCTID,我不再收到错误。效果很好。