相关疑难解决方法(0)

Hibernate可以使用MySQL的"ON DUPLICATE KEY UPDATE"语法吗?

MySQL支持一种" INSERT ... ON DUPLICATE KEY UPDATE ..."语法,允许您"盲目地"插入数据库,并回退到更新现有记录(如果存在).

当您需要快速事务隔离并且要更新的值依赖于数据库中已有的值时,这非常有用.

作为一个人为的例子,假设您想要计算在博客上查看故事的次数.使用此语法执行此操作的一种方法可能是:

 INSERT INTO story_count (id, view_count) VALUES (12345, 1)
 ON DUPLICATE KEY UPDATE set view_count = view_count + 1
Run Code Online (Sandbox Code Playgroud)

这比开始交易更有效,更有效,并且处理新故事登上头版时发生的不可避免的异常.

我们怎么能用Hibernate做同样的事情,或者实现同样的目标呢?

首先,Hibernate的HQL解析器将抛出异常,因为它不了解特定于数据库的关键字.事实上,HQL不喜欢任何显式插入,除非它是" INSERT ... SELECT ....".

其次,Hibernate将SQL限制为仅选择.如果您尝试呼叫,Hibernate将抛出异常session.createSQLQuery("sql").executeUpdate().

第三,saveOrUpdate在这种情况下,Hibernate 不符合要求.您的测试将通过,但如果您每秒有多个访问者,则会导致生产失败.

我真的要颠覆Hibernate吗?

java mysql orm hibernate

26
推荐指数
1
解决办法
2万
查看次数

优雅地处理EJB/JPA环境中的约束违规?

我在Glassfish v3应用服务器上使用EJB和JPA.我有一个实体类,我强迫其中一个字段与@Column注释是唯一的.

@Entity
public class MyEntity implements Serializable {

    private String uniqueName;

    public MyEntity() {
    }

    @Column(unique = true, nullable = false)
    public String getUniqueName() {
        return uniqueName;
    }

    public void setUniqueName(String uniqueName) {
        this.uniqueName = uniqueName;
    }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试将此字段设置为非唯一值的对象持久化时,当EJB容器管理的事务提交时,我得到一个异常(如预期的那样).

我有两个问题需要解决:

1)我得到的例外是无用的"javax.ejb.EJBException:Transaction aborted".如果我递归调用getCause()足够多次,我最终会得到更有用的"java.sql.SQLIntegrityConstraintViolationException",但是这个异常是EclipseLink实现的一部分,我真的不习惯依赖它的存在.

有没有更好的方法来获取JPA的详细错误信息?

2)EJB容器坚持记录此错误,即使我抓住它并处理它.

有没有更好的方法来处理这个错误,这将阻止Glassfish使用无用的异常信息混乱我的日志?

谢谢.

java database jpa java-ee ejb-3.0

18
推荐指数
2
解决办法
2万
查看次数

没有约束异常处理的Hibernate线程安全幂等upsert?

我有一些执行UPSERT的代码,也称为Merge。我想清理这段代码,具体地说,我想摆脱异常处理,并为这种简单的操作降低代码的整体冗长性和纯粹的复杂性。要求是插入每个项目,除非它已经存在:

public void batchInsert(IncomingItem[] items) {
    try(Session session = sessionFactory.openSession()) {
        batchInsert(session, items);
    }
    catch(PersistenceException e) {
        if(e.getCause() instanceof ConstraintViolationException) {
            logger.warn("attempting to recover from constraint violation");
            DateTimeFormatter dbFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
            items = Arrays.stream(items).filter(item -> {
                int n = db.queryForObject("select count(*) from rets where source = ? and systemid = ? and updtdate = ?::timestamp",
                        Integer.class,
                        item.getSource().name(), item.getSystemID(), 
                        dbFormat.format(item.getUpdtDateObj()));
                if(n != 0) {
                    logger.warn("REMOVED DUPLICATE: " +
                            item.getSource() + " " + item.getSystemID() + " " + …
Run Code Online (Sandbox Code Playgroud)

java hibernate jpa

6
推荐指数
2
解决办法
327
查看次数

标签 统计

java ×3

hibernate ×2

jpa ×2

database ×1

ejb-3.0 ×1

java-ee ×1

mysql ×1

orm ×1