|
24 | 24 | import org.hibernate.dialect.NullOrdering; |
25 | 25 | import org.hibernate.dialect.Replacer; |
26 | 26 | import org.hibernate.dialect.SelectItemReferenceStrategy; |
| 27 | +import org.hibernate.exception.ConstraintViolationException; |
| 28 | +import org.hibernate.exception.LockAcquisitionException; |
| 29 | +import org.hibernate.exception.spi.SQLExceptionConversionDelegate; |
27 | 30 | import org.hibernate.type.descriptor.jdbc.VarcharUUIDJdbcType; |
28 | 31 | import org.hibernate.dialect.function.CaseLeastGreatestEmulation; |
29 | 32 | import org.hibernate.dialect.function.CommonFunctionFactory; |
|
91 | 94 | import jakarta.persistence.TemporalType; |
92 | 95 |
|
93 | 96 | import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate; |
| 97 | +import static org.hibernate.internal.util.JdbcExceptionHelper.extractErrorCode; |
94 | 98 | import static org.hibernate.query.sqm.produce.function.FunctionParameterType.STRING; |
95 | 99 | import static org.hibernate.type.SqlTypes.BIGINT; |
96 | 100 | import static org.hibernate.type.SqlTypes.BINARY; |
@@ -562,46 +566,80 @@ public boolean supportsValuesListForInsert() { |
562 | 566 | return false; |
563 | 567 | } |
564 | 568 |
|
| 569 | + @Override |
| 570 | + public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() { |
| 571 | + return (sqlException, message, sql) -> |
| 572 | + switch ( extractErrorCode( sqlException ) ) { |
| 573 | + case -378, -233, -107, -113, -134, -143, -144, -154 -> |
| 574 | + //TODO: which of these are these are really LockTimeoutExceptions |
| 575 | + // rather than the more generic LockAcquisitionException? |
| 576 | + new LockAcquisitionException( message, sqlException, sql ); |
| 577 | + case -239, -268 -> |
| 578 | + new ConstraintViolationException( message, sqlException, sql, ConstraintViolationException.ConstraintKind.UNIQUE, |
| 579 | + getViolatedConstraintNameExtractor().extractConstraintName( sqlException ) ); |
| 580 | + case -691, -692 -> |
| 581 | + new ConstraintViolationException( message, sqlException, sql, ConstraintViolationException.ConstraintKind.FOREIGN_KEY, |
| 582 | + getViolatedConstraintNameExtractor().extractConstraintName( sqlException ) ); |
| 583 | + case -703, -391 -> |
| 584 | + new ConstraintViolationException( message, sqlException, sql, ConstraintViolationException.ConstraintKind.NOT_NULL, |
| 585 | + getViolatedConstraintNameExtractor().extractConstraintName( sqlException ) ); |
| 586 | + case -530 -> |
| 587 | + new ConstraintViolationException( message, sqlException, sql, ConstraintViolationException.ConstraintKind.CHECK, |
| 588 | + getViolatedConstraintNameExtractor().extractConstraintName( sqlException ) ); |
| 589 | + default -> null; |
| 590 | + }; |
| 591 | + } |
| 592 | + |
565 | 593 | @Override |
566 | 594 | public ViolatedConstraintNameExtractor getViolatedConstraintNameExtractor() { |
567 | 595 | return EXTRACTOR; |
568 | 596 | } |
569 | 597 |
|
570 | 598 | private static final ViolatedConstraintNameExtractor EXTRACTOR = |
571 | 599 | new TemplatedViolatedConstraintNameExtractor( sqle -> { |
572 | | - String constraintName; |
573 | | - switch ( JdbcExceptionHelper.extractErrorCode( sqle ) ) { |
574 | | - case -268: |
575 | | - constraintName = extractUsingTemplate( |
576 | | - "Unique constraint (", |
577 | | - ") violated.", |
578 | | - sqle.getMessage() |
579 | | - ); |
580 | | - break; |
581 | | - case -691: |
582 | | - constraintName = extractUsingTemplate( |
583 | | - "Missing key in referenced table for referential constraint (", |
584 | | - ").", |
585 | | - sqle.getMessage() |
586 | | - ); |
587 | | - break; |
588 | | - case -692: |
589 | | - constraintName = extractUsingTemplate( |
590 | | - "Key value for constraint (", |
591 | | - ") is still being referenced.", |
592 | | - sqle.getMessage() |
593 | | - ); |
594 | | - break; |
595 | | - default: |
596 | | - return null; |
| 600 | + final String constraintName = |
| 601 | + switch ( JdbcExceptionHelper.extractErrorCode( sqle ) ) { |
| 602 | + case -239, -268 -> |
| 603 | + extractUsingTemplate( |
| 604 | + "Unique constraint (", |
| 605 | + ") violated.", |
| 606 | + sqle.getMessage() |
| 607 | + ); |
| 608 | + case -691 -> |
| 609 | + extractUsingTemplate( |
| 610 | + "Missing key in referenced table for referential constraint (", |
| 611 | + ").", |
| 612 | + sqle.getMessage() |
| 613 | + ); |
| 614 | + case -692 -> |
| 615 | + extractUsingTemplate( |
| 616 | + "Key value for constraint (", |
| 617 | + ") is still being referenced.", |
| 618 | + sqle.getMessage() |
| 619 | + ); |
| 620 | + case -530 -> |
| 621 | + extractUsingTemplate( |
| 622 | + "Check constraint (", |
| 623 | + ") failed", |
| 624 | + sqle.getMessage() |
| 625 | + ); |
| 626 | + case -391 -> |
| 627 | + extractUsingTemplate( |
| 628 | + "null into column (", |
| 629 | + ")", |
| 630 | + sqle.getMessage() |
| 631 | + ); |
| 632 | + default -> null; |
| 633 | + }; |
| 634 | + |
| 635 | + if ( constraintName == null ) { |
| 636 | + return null; |
597 | 637 | } |
598 | | - |
599 | | - // strip table-owner because Informix always returns constraint names as "<table-owner>.<constraint-name>" |
600 | | - final int i = constraintName.indexOf( '.' ); |
601 | | - if ( i != -1 ) { |
602 | | - constraintName = constraintName.substring( i + 1 ); |
| 638 | + else { |
| 639 | + // strip table-owner because Informix always returns constraint names as "<table-owner>.<constraint-name>" |
| 640 | + final int index = constraintName.indexOf( '.' ); |
| 641 | + return index > 0 ? constraintName.substring( index + 1 ) : constraintName; |
603 | 642 | } |
604 | | - return constraintName; |
605 | 643 | } ); |
606 | 644 |
|
607 | 645 | @Override |
|
0 commit comments