简体   繁体   English

Liberty JavaEE 8 捕获 ConstraintViolationException

[英]Liberty JavaEE 8 catch ConstraintViolationException

Is there any way to catch org.hibernate.exception.ConstraintViolationException in Liberty application server ?有什么方法可以在 Liberty 应用程序服务器中捕获org.hibernate.exception.ConstraintViolationException吗?

I have a this repository code :我有一个这个存储库代码:

@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class MarketRepository {

    @PersistenceContext
    private EntityManager em;

    @Resource
    private UserTransaction tx;

    public void insert(Market market) {
        try {
            tx.begin();
            em.persist(market);
            tx.commit();
        } catch (Exception ignore) {
        }
    }
}     

I always receive this exception :我总是收到这个例外:

[INFO] Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
[INFO]  at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:109)
[INFO]  at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
[INFO]  at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
[INFO]  at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
[INFO]  at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:200)
[INFO]  at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3238)
[INFO]  at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3763)
[INFO]  at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:107)
[INFO]  at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604)
[INFO]  at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478)
[INFO]  at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:723)
[INFO]  at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475)
[INFO]  at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:348)
[INFO]  at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40)
[INFO]  at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102)
[INFO]  at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1360)
[INFO]  ... 20 more
[INFO] Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "ukmn9r4yewa9epwp1ekfsbm69gu"
[INFO]   Detail: Key (exchange, symbol)=(COINEX, ZECUSDT) already exists.
[INFO]  at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2533)
[INFO]  at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2268)
[INFO]  at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:313)
[INFO]  at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:448)
[INFO]  at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:369)
[INFO]  at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:159)
[INFO]  at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:125)
[INFO]  at jdk.internal.reflect.GeneratedMethodAccessor1090.invoke(Unknown Source)
[INFO]  at java.base/java.lang.reflect.Method.invoke(Method.java:567)
[INFO]  at org.postgresql.ds.PGPooledConnection$StatementHandler.invoke(PGPooledConnection.java:428)
[INFO]  at jdk.proxy11/jdk.proxy11.$Proxy136.executeUpdate(Unknown Source)
[INFO]  at com.ibm.ws.rsadapter.jdbc.WSJdbcPreparedStatement.executeUpdate(WSJdbcPreparedStatement.java:520)
[INFO]  at [internal classes]
[INFO]  at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197)
[INFO]  ... 31 more

this is my server.xml config :这是我的 server.xml 配置:

 <dataSource jndiName="jdbc/jta-datasource" transactional="true">
        <jdbcDriver id="database-driver" libraryRef="project-libs"/>
        <properties databaseName="${database.name}" serverName="${database.hostname}" portNumber="${database.port}"
                    user="${database.username}" password="${database.password}"/>
    </dataSource>    

so, I want to ignore this exception, but still receive that !所以,我想忽略这个异常,但仍然收到!

How can fix this problem ?如何解决这个问题?

UPDATE:更新:
persistence.xml持久化文件

<persistence 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"
             version="2.1">
    <persistence-unit name="db-connection" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>jdbc/jta-datasource</jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL10Dialect"/>
        </properties>
    </persistence-unit>
</persistence>    

MarketJob:市场工作:

import javax.ejb.*;

@Singleton
public class MarketJob {

    @EJB
    private MarketRepository repo;

    @Lock(LockType.READ)
    @Schedule(second = "59", minute = "59", hour = "*", persistent = false)
    private void execute() {
        List<Market> marketList = // read data from external api;
        for (Market market : marketList) {
            repo.insert(market);
        }
    }
}

If you use em.merge(market);如果你使用em.merge(market); instead of em.persist(market);而不是em.persist(market); JPA translates that to an insert-if-absent-else-update, which will avoid violating the constraint in your database that every (exchange, symbol) pairing be unique. JPA 将其转换为 insert-if-absent-else-update,这将避免违反数据库中每个(交换、符号)配对都是唯一的约束。

This may not work if the unique constraint isn't a primary key.如果唯一约束不是主键,这可能不起作用。 Or even if it is ... My experience is you just can't catch an exception that the persistence container is throwing.或者即使是......我的经验是你无法捕捉到持久性容器抛出的异常。 One solution would be to make sure there isn't already a record with the same exchange and symbol:一种解决方案是确保没有具有相同交换和符号的记录:

String jpql = "select count(*) from Market where m.exchange = ? and m.symbol = ?";
tx.begin();
int count = em.createQuery(jpql, Integer.class)
.setParameter(1, market.getExchange())
.setParameter(2, market.getSymbol()).getSingleResult();
if(count == 0){
  em.persist(market);
  tx.commit();
}

You just need to put arround the repo.insert(market) a try/catch block that catches SQLIntegrityConstraintViolationException , and do whatever you want in the catch block.您只需要在repo.insert(market)放置一个捕获SQLIntegrityConstraintViolationExceptiontry/catch块,然后在catch块中执行您想做的任何操作。

Off-topic recomendation for your code对您的代码的离题推荐

UserTransaction: At least in the example you are using you don't need that. UserTransaction:至少在您使用的示例中,您不需要它。 All Session Bean (aka EJB) (that is Stateless, Stateful and Singleton) provide transactionality by default.默认情况下,所有会话 Bean(又名 EJB)(即无状态、有状态和单例)都提供事务性。 That means that before any business method a new transaction will automatically start, and will commit it at the end of the method.这意味着在任何业务方法之前,一个新事务将自动启动,并在方法结束时提交。 If the method throws an Exception the transaction will automatically Rollback.如果该方法抛出异常,事务将自动回滚。

If the business method is called from another EJB it will reuse the same transaction.如果从另一个 EJB 调用业务方法,它将重用相同的事务。

That is the default behaviour, and is really really powerful, allowing to manage most of the business cases without manually managing transactions.这是默认行为,非常强大,允许管理大多数业务案例而无需手动管理事务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 捕获 ConstraintViolationException - 不起作用 - catch ConstraintViolationException - doesnt work 无法捕获 ConstraintViolationException - Can't catch ConstraintViolationException 如何在JavaEE 6中捕获OptimisticLockException? - How to catch OptimisticLockException in JavaEE 6? 无法在实体删除时捕获 ConstraintViolationException - Cant catch ConstraintViolationException on entity delete JPA:合并并持久化,捕获ConstraintViolationException - JPA: merge and persist,catch ConstraintViolationException JavaEE 全局捕获运行时异常 - JavaEE Globally Catch Runtime exception 为什么我无法在 Hibernate 中捕获 ConstraintViolationException? - Why can't I catch ConstraintViolationException in Hibernate? JavaEE Websphere Liberty没有根资源匹配请求,并且没有有效的jdbcDriver - JavaEE Websphere Liberty No root resource matching request & No valid jdbcDriver 如何检查,抛出和捕获bean的验证ConstraintViolationException - How to check, throw and catch bean's validation ConstraintViolationException 如何使用JUnit 5在Spring Boot中捕获Hibernate ConstraintViolationException(或Spring DataIntegrityViolationException?) - How to catch Hibernate ConstraintViolationException (or Spring DataIntegrityViolationException?) in Spring Boot with JUnit 5
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM