Oracle DB への永続化アクションを実行する @Transactional サービスがあります。固有の違反を破る永続化を実行すると、予想される rollbackException:ConstraintException が発生します。
問題は、(一意の制約を破っていなくても) 永続化するための後続の要求が同じ例外をスローすることです。
JPA がオブジェクトをクリアしてトランザクション マネージャーから永続化していないように見えますか? 私も近いですか?少し説明が必要です。
レポ:
@Repository
public class UserRepository {
@PersistenceContext(type=PersistenceContextType.EXTENDED)
private EntityManager em;
public User findUserById(long id){
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<User> query = builder.createQuery(User.class);
Root<User> root = query.from(User.class);
Predicate whereClause = builder.equal(root.get(User_.userId), id);
return em.createQuery(query.where(whereClause)).getSingleResult();
}
public User findUserByCredentials(String credentials){
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<User> query = builder.createQuery(User.class);
Root<User> root = query.from(User.class);
Predicate whereClause = builder.equal(root.get(User_.credentials), credentials);
return em.createQuery(query.where(whereClause)).getSingleResult();
}
public void registerUser(User user){
em.persist(user);
}
}
サービス実装:
@Transactional(readOnly=true)
@Service("userService")
public class UserServiceImpl implements UserService {
@Resource
private UserRepository userRepository;
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User findUserById(long id) {
return userRepository.findUserById(id);
}
public User findUserByCredentials(String credentials){
return userRepository.findUserByCredentials(credentials);
}
@Transactional(readOnly=false)
public void registerUser(User user){
userRepository.registerUser(user);
}
}
エンドポイントでスローされるエラー:
@PayloadRoot(localPart="RegisterUserRequest", namespace = "http://www.missingwire.com/schemas/User")
public RegisterUserResponseDocument registerUser(RegisterUserRequestDocument requestDoc){
RegisterUserRequest request = requestDoc.getRegisterUserRequest();
User user = new User();
user.setCredentials(request.getCredentials());
user.setPassword(request.getPassword());
user.setHonorRating(BigDecimal.valueOf(STARTING_USER_HONOR_RATING));
user.setAccountActive(true);
user.setDateCreated(new Date());
user.setVerified(false);
UserProfile userProfile = new UserProfile();
userProfile.setEmailAddress(request.getEmail());
userProfile.setFirstName(request.getFirstName());
userProfile.setLastName(request.getLastName());
userProfile.setDateCreated(new Date());
userProfile.setUser(user);
user.setUserProfile(userProfile);
**userService.registerUser(user);** //HERE IS THE EXCEPTION THROW
RegisterUserResponseDocument responseDoc = RegisterUserResponseDocument.Factory.newInstance();
RegisterUserResponse response = responseDoc.addNewRegisterUserResponse();
UserType userType = response.addNewUser();
userType.setAccountActive(user.getAccountActive());
userType.setCredentials(user.getCredentials());
userType.setDateCreated(DateConverter.convertDateToXML(user.getDateCreated()));
userType.setUserId(user.getUserId());
userType.setVerified(user.getVerified());
return responseDoc;
}
例外:
org.springframework.orm.jpa.JpaSystemException: トランザクションのコミット中にエラーが発生しました。ネストされた例外は javax.persistence.RollbackException: Error while committing the transaction at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:311) at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect. java:102) org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerSynchronization.convertException(ExtendedEntityManagerCreator.java:501) で org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerSynchronization.afterCommit(ExtendedEntityManagerCreator.java:481) で org.springframework .transaction.support.TransactionSynchronizationUtils.
oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10070) で oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:213) で org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70) ) org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268) で