Skip to content

Commit

Permalink
HHH-15570 allow @SqlInsert, @SqlUpdate, @SqlDelete for secondary tables
Browse files Browse the repository at this point in the history
  • Loading branch information
gavinking committed Nov 4, 2022
1 parent 28b2535 commit aef9ab2
Show file tree
Hide file tree
Showing 17 changed files with 443 additions and 175 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,7 @@ You can see the expected order by enabling debug logging, so Hibernate can print
To see the expected sequence, remember to not include your custom SQL through annotations or mapping files as that will override the Hibernate generated static SQL.
====

Overriding SQL statements for secondary tables is also possible using `@org.hibernate.annotations.Table` and the `sqlInsert`, `sqlUpdate`, `sqlDelete` attributes.
Overriding SQL statements for secondary tables is also possible.

[[sql-custom-crud-secondary-table-example]]
.Overriding SQL statements for secondary tables
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,24 +90,24 @@ public void test_sql_custom_crud() {
//tag::sql-custom-crud-secondary-table-example[]
@Entity(name = "Person")
@Table(name = "person")
@SecondaryTable(name = "person_details",
pkJoinColumns = @PrimaryKeyJoinColumn(name = "person_id"))
@SQLInsert(
sql = "INSERT INTO person (name, id, valid) VALUES (?, ?, true) "
)
@SQLDelete(
sql = "UPDATE person SET valid = false WHERE id = ? "
)
@SecondaryTable(name = "person_details",
pkJoinColumns = @PrimaryKeyJoinColumn(name = "person_id"))
@org.hibernate.annotations.Table(
appliesTo = "person_details",
sqlInsert = @SQLInsert(
sql = "INSERT INTO person_details (image, person_id, valid) VALUES (?, ?, true) ",
check = ResultCheckStyle.COUNT
),
sqlDelete = @SQLDelete(
sql = "UPDATE person_details SET valid = false WHERE person_id = ? "
)
)
)
@SQLInsert(
table = "person_details",
sql = "INSERT INTO person_details (image, person_id, valid) VALUES (?, ?, true) ",
check = ResultCheckStyle.COUNT
)
@SQLDelete(
table = "person_details",
sql = "UPDATE person_details SET valid = false WHERE person_id = ? "
)

@Loader(namedQuery = "find_valid_person")
@NamedNativeQueries({
@NamedNativeQuery(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,36 @@
package org.hibernate.annotations;

/**
* Possible styles of checking return codes on SQL INSERT, UPDATE and DELETE queries.
* Enumerates strategies for checking JDBC return codes for custom SQL DML queries.
* <p>
* Return code checking is used to verify that a SQL statement actually had the
* intended effect, for example, that an {@code UPDATE} statement actually changed
* the expected number of rows.
*
* @author L�szl� Benke
*/
public enum ResultCheckStyle {
/**
* Do not perform checking. Might mean that the user really just does not want any checking. Might
* also mean that the user is expecting a failure to be indicated by a {@link java.sql.SQLException} being
* thrown (presumably from a {@link java.sql.CallableStatement} which is performing explicit checks and
* propagating failures back through the driver).
* No return code checking. Might mean that no checks are required, or that
* failure is indicated by a {@link java.sql.SQLException} being thrown, for
* example, by a {@link java.sql.CallableStatement stored procedure} which
* performs explicit checks.
*/
NONE,
/**
* Perform row-count checking. Row counts are the int values returned by both
* {@link java.sql.PreparedStatement#executeUpdate()} and
* {@link java.sql.Statement#executeBatch()}. These values are checked
* against some expected count.
* Row count checking. A row count is an integer value returned by
* {@link java.sql.PreparedStatement#executeUpdate()} or
* {@link java.sql.Statement#executeBatch()}. The row count is checked
* against an expected value. For example, the expected row count for
* an {@code INSERT} statement is always 1.
*/
COUNT,
/**
* Essentially the same as {@link #COUNT} except that the row count actually
* comes from an output parameter registered as part of a
* {@link java.sql.CallableStatement}. This style explicitly prohibits
* statement batching from being used...
* Essentially identical to {@link #COUNT} except that the row count is
* obtained via an output parameter of a {@link java.sql.CallableStatement
* stored procedure}.
* <p>
* Statement batching is disabled when {@code PARAM} is selected.
*/
PARAM
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package org.hibernate.annotations;

import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

Expand All @@ -15,12 +16,14 @@
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
* Custom SQL statement for delete of an entity/collection.
* Specifies a custom SQL DML statement to be used in place of the default SQL generated by
* Hibernate when an entity or collection row is deleted from the database.
*
* @author L�szl� Benke
*/
@Target( {TYPE, FIELD, METHOD} )
@Retention( RUNTIME )
@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
@Repeatable(SQLDeletes.class)
public @interface SQLDelete {
/**
* Procedure name or SQL DELETE statement.
Expand All @@ -36,4 +39,14 @@
* For persistence operation what style of determining results (success/failure) is to be used.
*/
ResultCheckStyle check() default ResultCheckStyle.NONE;

/**
* The name of the table in the case of an entity with {@link jakarta.persistence.SecondaryTable
* secondary tables}, defaults to the primary table.
*
* @return the name of the table
*
* @since 6.2
*/
String table() default "";
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,21 @@
package org.hibernate.annotations;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
* Custom SQL statement for delete of all of a collection's elements.
* Specifies a custom SQL DML statement to be used in place of the default SQL generated by
* Hibernate when an entire collection is deleted from the database.
*
* @author L�szl� Benke
*/
@Target( {TYPE, FIELD, METHOD} )
@Retention( RetentionPolicy.RUNTIME )
@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
public @interface SQLDeleteAll {
/**
* Procedure name or SQL DELETE statement.
Expand All @@ -36,4 +37,14 @@
* For persistence operation what style of determining results (success/failure) is to be used.
*/
ResultCheckStyle check() default ResultCheckStyle.NONE;

/**
* The name of the table in the case of an entity with {@link jakarta.persistence.SecondaryTable
* secondary tables}, defaults to the primary table.
*
* @return the name of the table
*
* @since 6.2
*/
String table() default "";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.annotations;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
* A grouping of {@link SQLDelete}s.
*
* @since 6.2
* @author Gavin King
*/
@Target(TYPE)
@Retention(RUNTIME)
public @interface SQLDeletes {
SQLDelete[] value();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package org.hibernate.annotations;

import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

Expand All @@ -15,12 +16,14 @@
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
* Custom SQL statement for insertion of an entity/collection.
* Specifies a custom SQL DML statement to be used in place of the default SQL generated by
* Hibernate when an entity or collection row is inserted in the database.
*
* @author L�szl� Benke
*/
@Target( {TYPE, FIELD, METHOD} )
@Retention( RUNTIME )
@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
@Repeatable(SQLInserts.class)
public @interface SQLInsert {
/**
* Procedure name or SQL INSERT statement.
Expand All @@ -36,4 +39,14 @@
* For persistence operation what style of determining results (success/failure) is to be used.
*/
ResultCheckStyle check() default ResultCheckStyle.NONE;

/**
* The name of the table in the case of an entity with {@link jakarta.persistence.SecondaryTable
* secondary tables}, defaults to the primary table.
*
* @return the name of the secondary table
*
* @since 6.2
*/
String table() default "";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.annotations;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
* A grouping of {@link SQLInsert}s.
*
* @since 6.2
* @author Gavin King
*/
@Target(TYPE)
@Retention(RUNTIME)
public @interface SQLInserts {
SQLInsert[] value();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package org.hibernate.annotations;

import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

Expand All @@ -15,12 +16,14 @@
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
* Custom SQL statement for update of an entity/collection.
* Specifies a custom SQL DML statement to be used in place of the default SQL generated by
* Hibernate when an entity or collection row is updated in the database.
*
* @author L�szl� Benke
*/
@Target( {TYPE, FIELD, METHOD} )
@Retention( RUNTIME )
@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
@Repeatable(SQLUpdates.class)
public @interface SQLUpdate {
/**
* Procedure name or SQL UPDATE statement.
Expand All @@ -36,4 +39,14 @@
* For persistence operation what style of determining results (success/failure) is to be used.
*/
ResultCheckStyle check() default ResultCheckStyle.NONE;

/**
* The name of the table in the case of an entity with {@link jakarta.persistence.SecondaryTable
* secondary tables}, defaults to the primary table.
*
* @return the name of the table
*
* @since 6.2
*/
String table() default "";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.annotations;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
* A grouping of {@link SQLUpdate}s.
*
* @since 6.2
* @author Gavin King
*/
@Target(TYPE)
@Retention(RUNTIME)
public @interface SQLUpdates {
SQLUpdate[] value();
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*
* @see jakarta.persistence.SecondaryTable
*
* @since 6.2
* @author Gavin King
*/
@Target(TYPE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
* A grouping of {@link SecondaryRows}.
* A grouping of {@link SecondaryRow}s.
*
* @since 6.2
* @author Gavin King
*/
@Target(TYPE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,25 +100,28 @@
* <p>
* <em>Only applies to secondary tables.</em>
*
* @see SQLInsert
* @deprecated use {@link SQLInsert#table()} to specify the secondary table
*/
@Deprecated(since="6.2")
SQLInsert sqlInsert() default @SQLInsert(sql="");

/**
* Defines a custom SQL update statement.
* <p>
* <em>Only applies to secondary tables.</em>
*
* @see SQLUpdate
* @deprecated use {@link SQLInsert#table()} to specify the secondary table
*/
@Deprecated(since="6.2")
SQLUpdate sqlUpdate() default @SQLUpdate(sql="");

/**
* Defines a custom SQL delete statement.
* <p>
* <em>Only applies to secondary tables.</em>
*
* @see SQLDelete
* @deprecated use {@link SQLInsert#table()} to specify the secondary table
*/
@Deprecated(since="6.2")
SQLDelete sqlDelete() default @SQLDelete(sql="");
}

0 comments on commit aef9ab2

Please sign in to comment.