当前位置: 首页 > 面试题库 >

休眠异常处理

薛华容
2023-03-14
问题内容

我有一个“复杂”的问题。

我正在使用Hibernate / JPA与数据库进行事务。

我不是DBA,客户端使用了我的应用程序,即RESTful
Web服务。我的问题是数据库已更改(不是很频繁,但仍在更改)。另外,客户端并不总是尊重我的应用程序的输入(长度,类型等)。发生这种情况时,Hibernate会引发异常。异常很难翻译和从日志中读取,因为它具有嵌套的异常并且由很多文本组成:就像我说的那样,很难理解。

我想知道是否有可能在实体级别处理异常,并抛出定制的异常。

感谢您的耐心配合和事先的帮助。

编辑:

最后,我设法做自己想做的事,不确定这样做是否 正确

App.java

package com.mc;

import org.hibernate.Session;  
import com.mc.stock.Stock;  
import com.mc.util.HibernateUtil;  
import javax.persistence.EntityManager;

public class App {

    public static void main(String[] args) {  
        Set<ConstraintViolation<Stock>> violations;
        validator = Validation.buildDefaultValidatorFactory().getValidator();
        Scanner scan = new Scanner(System.in);

        EntityManager em = null;

        System.out.println("Hibernate one to many (Annotation)");
        Session session = HibernateUtil.getSessionFactory().openSession();

        session.beginTransaction();


        Stock stock = new Stock();
        String nextLine = scan.nextLine();
        stock.setStockCode(nextLine.toString());
        nextLine = scan.nextLine();
        stock.setStockName(nextLine.toString());


        violations = validator.validate(stock);
        if (violations.size() > 0) {
            StringBuilder excepcion = new StringBuilder();
            for (ConstraintViolation<Stock> violation : violations) {
                excepcion.append(violation.getMessageTemplate());
                excepcion.append("\n");
            }
            System.out.println(excepcion.toString());
        }
        session.save(stock);
        session.getTransaction().commit();
    }  
}

FieldMatch.java

package com.mc.constraints;

import com.mc.constraints.impl.FieldMatchValidator;

import javax.validation.Constraint;  
import javax.validation.Payload;  
import java.lang.annotation.Documented;  
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;  
import static java.lang.annotation.ElementType.TYPE;  
import java.lang.annotation.Retention;  
import static java.lang.annotation.RetentionPolicy.RUNTIME;  
import java.lang.annotation.Target;

@Target({TYPE, ANNOTATION_TYPE})  
@Retention(RUNTIME)  
@Constraint(validatedBy = FieldMatchValidator.class)  
@Documented  
public @interface FieldMatch {

    String message() default "{constraints.fieldmatch}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    String first();

    String second();

    @Target({TYPE, ANNOTATION_TYPE})  
    @Retention(RUNTIME)  
    @Documented  
    @interface List {

        FieldMatch[] value();  
    }  
}

FieldMatchValidator.java

package com.mc.constraints.impl;

import javax.validation.ConstraintValidator;  
import javax.validation.ConstraintValidatorContext;  
import com.mc.constraints.FieldMatch;  
import org.apache.commons.beanutils.BeanUtils;

public class FieldMatchValidator implements ConstraintValidator<FieldMatch, Object> {

    private String firstFieldName;  
    private String secondFieldName;

    @Override  
    public void initialize(final FieldMatch constraintAnnotation) {  
        firstFieldName = constraintAnnotation.first();  
        secondFieldName = constraintAnnotation.second();  
    }

    @Override  
    public boolean isValid(final Object value, final ConstraintValidatorContext context) {  
        try {  
            final Object firstObj = BeanUtils.getProperty(value, firstFieldName);  
            final Object secondObj = BeanUtils.getProperty(value, secondFieldName);

            return firstObj == null && secondObj == null || firstObj != null && firstObj.equals(secondObj);  
        } catch (final Exception ignore) {  
            // ignore  
        }  
        return true;  
    }  
}

股票.java

package com.mc.stock;

import com.mc.constraints.FieldMatch;  
import java.io.Serializable;  
import java.util.HashSet;  
import java.util.Set;  
import javax.persistence.Basic;  
import javax.persistence.Column;  
import javax.persistence.Entity;  
import javax.persistence.GeneratedValue;  
import javax.persistence.GenerationType;  
import javax.persistence.Id;  
import javax.persistence.NamedQueries;  
import javax.persistence.NamedQuery;  
import javax.persistence.OneToMany;  
import javax.persistence.SequenceGenerator;  
import javax.persistence.Table;  
import javax.xml.bind.annotation.XmlRootElement;  
import javax.xml.bind.annotation.XmlTransient;  
import org.hibernate.annotations.Cascade;  
import org.hibernate.annotations.CascadeType;  
import org.hibernate.validator.constraints.Length;

@Entity  
@Table(name = "STOCK")  
@XmlRootElement  
@NamedQueries({  
    @NamedQuery(name = "Stock.findAll", query = "SELECT s FROM Stock s"),  
    @NamedQuery(name = "Stock.findByStockId", query = "SELECT s FROM Stock s WHERE s.stockId = :stockId"),  
    @NamedQuery(name = "Stock.findByStockCode", query = "SELECT s FROM Stock s WHERE s.stockCode = :stockCode"),  
    @NamedQuery(name = "Stock.findByStockName", query = "SELECT s FROM Stock s WHERE s.stockName = :stockName")})  
@FieldMatch.List({  
    @FieldMatch(first = "stockCode", second = "stockName", message = "Code and Stock must have same value")  
})  
public class Stock implements Serializable {

    private static final long serialVersionUID = 1L;  
    @Id  
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_stock_id")  
    @SequenceGenerator(name = "seq_stock_id", sequenceName = "seq_stock_id", initialValue = 1, allocationSize = 1)  
    @Basic(optional = false)  
    @Column(name = "STOCK_ID", unique = true, nullable = false)  
    private Integer stockId;  
    @Column(name = "STOCK_CODE")  
    private String stockCode;  
    @Length(min = 1, max = 20, message = "{wrong stock name length}")  
    @Column(name = "STOCK_NAME")  
    private String stockName;

    public Stock() {  
    }

    public Stock(Integer stockId) {  
        this.stockId = stockId;  
    }

    public Integer getStockId() {  
        return stockId;  
    }

    public void setStockId(Integer stockId) {  
        this.stockId = stockId;  
    }

    public String getStockCode() {  
        return stockCode;  
    }

    public void setStockCode(String stockCode) {  
        this.stockCode = stockCode;  
    }

    public String getStockName() {  
        return stockName;  
    }

    public void setStockName(String stockName) {  
        this.stockName = stockName;  
    }

    @Override  
    public int hashCode() {  
        int hash = 0;  
        hash += (stockId != null ? stockId.hashCode() : 0);  
        return hash;  
    }

    @Override  
    public boolean equals(Object object) {  
        // TODO: Warning - this method won't work in the case the id fields are not set  
        if (!(object instanceof Stock)) {  
            return false;  
        }  
        Stock other = (Stock) object;  
        if ((this.stockId == null && other.stockId != null) || (this.stockId != null && !this.stockId.equals(other.stockId))) {  
            return false;  
        }  
        return true;  
    }

    @Override  
    public String toString() {  
        return "com.mc.stock.Stock[ stockId=" + stockId + " ]";  
    }  
}

HibernateUtil.java

package com.mc.util;

import org.hibernate.SessionFactory;  
import org.hibernate.cfg.Configuration;

public class HibernateUtil {

    private static final SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {  
        try {  
            // Create the SessionFactory from hibernate.cfg.xml  
            return new Configuration().configure().buildSessionFactory();  
        } catch (Throwable ex) {  
            // Make sure you log the exception, as it might be swallowed  
            System.err.println("Initial SessionFactory creation failed." + ex);  
            throw new ExceptionInInitializerError(ex);  
        }  
    }

    public static SessionFactory getSessionFactory() {  
        return sessionFactory;  
    }

    public static void shutdown() {  
        // Close caches and connection pools  
        getSessionFactory().close();  
    }  
}

Oracle数据库结构

CREATE TABLE stock  
(  
    STOCK_ID  NUMBER(5)  NOT NULL ,  
    STOCK_CODE  VARCHAR2(10)  NULL ,  
    STOCK_NAME  VARCHAR2(20)  NULL   
);

ALTER TABLE stock  
    add CONSTRAINT PK_STOCK_ID  PRIMARY KEY (STOCK_ID);

create sequence seq_stock_id   
   start with 1   
   increment by 1   
   nomaxvalue;

问题答案:

在获得数据库级别之前,我倾向于做很多验证。看看Hibernate
Validator,http:
//www.hibernate.org/subprojects/validator.html,它是JSR-303的参考实现。

使用标准注释,您可以强制约束并获得良好的错误消息,然后再尝试将实体放入数据库中。

我相信这将使您能够按要求在实体级别进行验证。



 类似资料:
  • 问题内容: 我在注释和上遇到了问题。在Hibernate中运行代码时,我得到: 引起原因:org.hibernate.PropertyAccessException:无法通过com.test.entities.EmployeeId.serverId的反射设置器设置字段值 但是,让我们从头开始…我有一个实体的复合主键,它由指向其他两个实体(和)的外键组成。为了设计简洁,我在Employee实体中使用

  • 问题内容: 从Weblogic 11c切换到Weblogic 12c后,出现此异常: 我发现了有关该主题的其他问题,但是所有解决方案都是关于错误的库的(Vaadin 7-Bean Validation )。我认为我的hibernate-validator与bean验证器库匹配。这是我在WEB-INF / lib中拥有的: 可能是由其他依赖性引起的吗? 编辑 我目前在我的weblogic-appli

  • 问题内容: 尝试将结果集强制转换为映射类时,我收到了hibernate类的类强制转换异常…我能够查看返回的结果集中的数据…但是它以Object []的形式返回我可以将Object []设置为List …我可以正确地进行hibernate映射吗?我从查询中获取了正确的数据,但映射不正确… 映射 映射类 参加班 主要 问题答案: 对于测试,我建议您在产生类强制转换异常的语句周围放置一个try-catc

  • 问题内容: 我正在使用hibernate和hql在Java代码中进行查询。但是我有这样一个例外: 我不明白“ 0”的含义。以下是一些带有示例的细节: 我有几个表加入hql。表格如下: 类: hql: 查询: 结果是对象“ A”的列表,其中包含收集的长度和单位。我不明白为什么会遇到这个例外。请给一些建议。 更新: 我编写了一个ResultTransformer并输出所有“别名”以查看问题: 似乎它还

  • 问题内容: 我正在尝试处理重量级元素(图像)的收集。集合的大小在8000-50000个条目之间变化。但是由于某种原因,在处理了1800-1900个条目之后,我的程序因java.lang.OutOfMemoryError:Java堆空间而掉线。 以我的理解,每次调用session.getTransaction()。commit()程序都应该释放堆内存,但是看起来它永远不会发生。我做错了什么?这是代码

  • 问题内容: 目前,我在 每个 Controller方法中 都 重复了以下代码: 这是正确的方法还是有更好的方法,也许在一个我可以引用的单独的类中?如果是这样,怎么办?每当我尝试将其放在单独的类中并从其他类中引用它时,它都会失败。 编辑 :我正在尝试使用尽可能少的外部库。如果Java在JDK中内置了ORM / JPA实现,我就不会使用Hibernate。 问题答案: 我本人已经遇到了很多次。通常,我