【问题标题】:Error:Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.DatabaseException错误:异常 [EclipseLink-4002](Eclipse 持久性服务 - 2.4.1.v20121003-ad44345):org.eclipse.persistence.exceptions.DatabaseException
【发布时间】:2013-05-23 06:27:45
【问题描述】:

由于违反主键约束,我收到此错误我的问题是如何捕获所有这些异常。

HTTP ERROR 500

Problem accessing /persist_role_servlet. Reason:

Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Duplicate entry 'sd' for key 'PRIMARY'
Error Code: 1062
Call: INSERT INTO ROLE (ROLE_ID, ROLE_DESC, ROLE_NAME) VALUES (?, ?, ?)
    bind => [3 parameters bound]
Query: InsertObjectQuery(com.example.rolessample.role@3f1179)
Caused by:

javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Duplicate entry 'sd' for key 'PRIMARY'
Error Code: 1062
Call: INSERT INTO ROLE (ROLE_ID, ROLE_DESC, ROLE_NAME) VALUES (?, ?, ?)
    bind => [3 parameters bound] 

这是我的 servlet 代码:

package com.example.rolessample;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class persist_role_servlet extends HttpServlet {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        PrintWriter out = resp.getWriter();

        String role_id = req.getParameter("role_id");
        String role_name = req.getParameter("role_name");
        String role_desc = req.getParameter("role_desc");

        String comp_id = "";
        String parent_comp = "";
        String permission = "";

        role r = new role();

        r.setRole_id(role_id);
        r.setRole_name(role_name);
        r.setRole_desc(role_desc);


        //Persisting the role bean .

        EntityManager em = EMF.get().createEntityManager();
        EntityTransaction tx = em.getTransaction();

            tx.begin();
            em.persist(r);
            tx.commit();




        String[] checkboxNamesList = req.getParameterValues("component");

        for (int i = 0; i < checkboxNamesList.length; i++) {

            String[] myCheckBoxValue = req
                    .getParameterValues(checkboxNamesList[i]);

            //If null, it means checkbox is not in request, so unchecked
            if (myCheckBoxValue == null) {

                component comp = new component();


                //Logic for finding component's name,component parent and their permissions.
                String S1 = checkboxNamesList[i];
                int lastUnderscore = S1.lastIndexOf("_");
                permission = S1.substring(lastUnderscore + 1);
                comp_id = S1.substring(0, lastUnderscore);
                lastUnderscore = comp_id.lastIndexOf("_");
                parent_comp = comp_id.substring(0, lastUnderscore);



                comp.setComp_id(comp_id);
                comp.setParent_comp(parent_comp);
                comp.setRole_id(role_id);
                comp.setPermission(permission);

                //Persisting component bean .


                    tx.begin();
                    em.persist(comp);
                    tx.commit();

            }
            // if is there, it means checkbox checked
            else {
                out.println(checkboxNamesList[i] + "=checked");

            }

        }

        // resp.setHeader("Refresh", "0; url=/guestbook.jsp");
    }

}

【问题讨论】:

  • 数据库操作直接在 servlet 中,糟糕的设计和缺乏异常处理机制。参考文档 - docs.oracle.com/javase/tutorial/essential/exceptions
  • 如何避免异常处理机制?我的意思是,它应该抛出一个异常,我应该处理所有这些。但问题是我不知道哪个异常捕获以及如何捕获?
  • 你可以尝试在日志中找到它,它是SQLException 包裹在DatabaseException 中,抓住后面的。您是否尝试过浏览提供的链接,这将帮助您更好地理解。
  • try{ //持久化组件bean . tx.begin(); em.persist(comp); tx.commit(); } catch (SQLException ex) { System.err.println("Caught IOException: " + ex.getMessage()); }

标签: java google-app-engine servlets jpa


【解决方案1】:

由于你使用的是 JPA,它会抛出你

org.eclipse.persistence.exceptions

但是你应该捕捉到 SQL Exception 并且从中你可以得到 SQL STATE

SQLSTATE 23000 ==> 违反完整性约束

尝试如下图实现

EntityManager em = EMF.get().createEntityManager();
EntityTransaction tx = em.getTransaction();
try {
   tx.begin();
   em.persist(r);
   tx.commit();
} catch (PersistenceException ex) {
Throwable t = getLastThrowable(ex);  //fetching Internal Exception
SQLException exxx = (SQLException) t;  //casting Throwable object to SQL Exception
System.out.println(exxx.getSQLState());
if(exxx.getSQLState()==23000) // Integrity constraint violation
{
 //Custom Bussiness Logic
}

访问内部异常的方法礼貌Rupesh Kumar Kushwaha博客

private Throwable getLastThrowable(Exception e) {
Throwable t = null;
for(t = e.getCause(); t.getCause() != null; t = t.getCause());
return t;
} 

希望这有效:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-05
    • 2011-09-15
    • 2017-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多