| 
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