如何处理RollbackException和约束违规

时间:2019-06-05 07:15:58

标签: java mysql hibernate spring-boot

我有两个桌子。一个是商人,另一个是地址。我正在验证地址表。商家和地址是一对多的关系。

这是我的商人表:

@Getter
    @Setter
    @Entity
    @Table(name = "merchant")
    public class Merchant extends Auditable<String> {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY) // Auto generate Id...
        @Column(name = "id")
        private Long id;

        @NotBlank(message = "Id no is required")
        @Size(min = 1, max = 20, message
                = "Id No must be between 1 and 20 characters")
        @Column(name = "id_no")
        private String idNo;

        @NotBlank(message = "Id type is required")
        @Column(name = "id_type")
        private String idType;

        @NotBlank(message = "Email id is required")
        @Email(message = "Email should be valid")
        @Column(name = "email_id")
        private String emailId;

        @NotBlank(message = "Name is required")
        @Size(min = 1, max = 40, message
                = "Merchant name must be between 1 and 40 characters")
        @Column(name = "name")
        private String name;

        @AssertTrue
        @NotNull(message = "Status is required")
        @Column(name = "status")
        private boolean status;

        @Column(name = "created_by")
        private String createdBy;

        @Column(name = "modified_by")
        private String modifiedBy;

        @ManyToMany(fetch = FetchType.LAZY, mappedBy="merchantSet")
        @Getter(onMethod = @__( @JsonIgnore))
        @Setter
        private Set<Product> productSet = new HashSet<Product>();

        @OneToMany(fetch = FetchType.LAZY,cascade = {CascadeType.MERGE}, mappedBy = "merchant")
        @NotEmpty(message = "Contact is required")
        private Set<Contact> contacts = new HashSet<Contact>(
                0);

        @OneToMany(fetch = FetchType.LAZY, cascade = {CascadeType.MERGE}, mappedBy = "merchant")
        @NotEmpty(message = "Address is required")
        private Set<Address> addresses = new HashSet<Address>(
                0);
    }

这是我的地址类别:

   @Getter
    @Setter
    @Entity
    public class Address extends Auditable<String> {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id")
        private Long id;

        @NotBlank(message = "Line1 is required")
        @Column(name = "line_1")
        private String line1;

        @NotBlank(message = "Line2 is required")
        @Column(name = "line_2")
        private String line2;

        @NotBlank(message = "Line3 is required")
        @Column(name = "line_3")
        private String line3;

        @NotBlank(message = "City is required")
        @Column(name = "city")
        private String city;

        @NotBlank(message = "Country is required")
        @Column(name = "country")
        private String country;

        @NotBlank(message = "ZipCode is required")
        @Column(name = "zip_code")
        private String zipCode;

        @NotBlank(message = "Type is required")
        @Column(name = "type")
        private String type;

        @NotBlank(message = "Owner type is required")
        @Column(name = "owner_type")
        private String ownerType;

        @Column(name = "created_by")
        private Long createdBy;

        @Column(name = "modified_by")
        private Long modifiedBy;

        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "merchant_id", nullable = false)
        @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
        @Getter(onMethod = @__( @JsonIgnore))
        @Setter
        private Merchant merchant;
    }

当我将地址行更新为空值时,会引发错误:

 2019-06-05 12:37:43.642 ERROR 8916 --- [0.0-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction] with root cause

javax.validation.ConstraintViolationException: Validation failed for classes [com.digiratina.islandgreen.model.Address] during update time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
    ConstraintViolationImpl{interpolatedMessage='Line2 is required', propertyPath=line2, rootBeanClass=class com.digiratina.islandgreen.model.Address, messageTemplate='Line2 is required'}
]
    at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:140) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreUpdate(BeanValidationEventListener.java:88) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.action.internal.EntityUpdateAction.preUpdate(EntityUpdateAction.java:248) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:119) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:478) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:356) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1454) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:511) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3283) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2479) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:473) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:178) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:39) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:271) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:98) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:532) ~[spring-orm-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:746) ~[spring-tx-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:714) ~[spring-tx-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.spring

我添加了句柄ConstraintViolationException来获取该异常消息。如何解决这个问题呢。我尝试了很多方法来处理此异常,但是没有用。抛出RollbackException。

我的商家更新服务是

public MerchantDTO updateMerchant(MerchantDTO merchantDTO, Long id) throws ClassNotFoundException, ConstraintViolationException {
        Merchant merchant = (Merchant) transformService.convertToEntity(merchantDTO, Constant.MERCHANT_ENTITY_CLASS);
        if(merchant.getAddresses().size() > 5) throw new MaximumValueExceptionHandler();
        if(merchant.getAddresses().size() <= 0) throw new MinimumValueExceptionHandler();
        if(merchant.getContacts().size() <= 0) throw new MinimumValueExceptionHandler();
        if(merchant.getContacts().size() > 3) throw new MaximumValueExceptionHandler();
        if (!merchantRepository.existsById(id)) throw new MerchantExceptionHandler();
        Merchant oldMerchant = merchantRepository.findMerchantById(id);
        if(merchantRepository.findByEmailId(merchant.getEmailId()) == null ||oldMerchant.getEmailId().equals(merchant.getEmailId())) {

            oldMerchant.setCreatedBy(merchant.getCreatedBy());
            oldMerchant.setEmailId(merchant.getEmailId());
            oldMerchant.setIdNo(merchant.getIdNo());
            oldMerchant.setIdType(merchant.getIdType());
            oldMerchant.setModifiedBy(merchant.getModifiedBy());
            oldMerchant.setName(merchant.getName());
            oldMerchant.setStatus(merchant.isStatus());
            merchant.getAddresses().forEach(address -> {
                Merchant merchant1 = new Merchant();
                if (address.getId() == null) {
                    merchant1.setId(id);
                    address.setMerchant(merchant1);
                    addressRepository.save(address);
                }
                if (!addressRepository.existsById(address.getId())) throw new AddressExceptionHandler();
                Address oldAddress = addressRepository.findAddressById(address.getId());
                oldAddress.setCity(address.getCity());
                oldAddress.setCountry(address.getCountry());
                oldAddress.setCreatedBy(address.getCreatedBy());
                oldAddress.setLine1(address.getLine1());
                oldAddress.setLine2(address.getLine2());
                oldAddress.setLine3(address.getLine3());
                oldAddress.setModifiedBy(address.getModifiedBy());
                oldAddress.setOwnerType(address.getOwnerType());
                oldAddress.setType(address.getType());
                oldAddress.setZipCode(address.getZipCode());
                merchant1.setId(id);
                oldAddress.setMerchant(merchant1);
                addressRepository.save(oldAddress);
            });

            merchant.getContacts().forEach(contact -> {
                Merchant merchant1 = new Merchant();
                if (contact.getId() == null) {
                    merchant1.setId(id);
                    contact.setMerchant(merchant1);
                    contactRepository.save(contact);
                }
                if (!contactRepository.existsById(contact.getId())) throw new ContactExceptionHandler();
                Contact oldContact = contactRepository.findContactById(contact.getId());
                oldContact.setContactNo(contact.getContactNo());
                merchant1.setId(id);
                oldContact.setMerchant(merchant1);
                contactRepository.save(oldContact);

            });

            Merchant newMerchant = merchantRepository.save(oldMerchant);
            return (MerchantDTO) transformService.convertToDto(newMerchant, Constant.MERCHANT_DTO_CLASS);
        }
       return null;
    }

1 个答案:

答案 0 :(得分:0)

@NotBlank(消息=“必须输入Line1”)抛出

  

javax.validation.ConstraintViolationException

但是从代码

catch (org.hibernate.exception.ConstraintViolationException e) {
    System.out.println(e.getMessage());
}

您正在将其作为休眠异常捕获,因此将不会对其进行处理。