Skip to content

Commit

Permalink
second solution for result set mappings
Browse files Browse the repository at this point in the history
  • Loading branch information
gavinking committed Dec 20, 2024
1 parent 7ae782e commit f6c5bab
Show file tree
Hide file tree
Showing 13 changed files with 168 additions and 73 deletions.
12 changes: 0 additions & 12 deletions api/src/main/java/jakarta/persistence/ColumnResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

package jakarta.persistence;

import java.lang.annotation.Annotation;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
Expand Down Expand Up @@ -81,15 +80,4 @@
* @since 2.1
*/
Class<?> type() default void.class;

record Map(String name, Class<?> type)
implements ColumnResult, SqlResultSetMapping.MappingElement {
Map(String name) {
this(name, void.class);
}
@Override
public Class<? extends Annotation> annotationType() {
return ColumnResult.class;
}
}
}
9 changes: 0 additions & 9 deletions api/src/main/java/jakarta/persistence/ConstructorResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

package jakarta.persistence;

import java.lang.annotation.Annotation;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
Expand Down Expand Up @@ -88,12 +87,4 @@
* {@linkplain #targetClass target class}, in order.
*/
ColumnResult[] columns();

record Map(Class<?> targetClass, ColumnResult... columns)
implements ConstructorResult, SqlResultSetMapping.MappingElement {
@Override
public Class<? extends Annotation> annotationType() {
return ConstructorResult.class;
}
}
}
10 changes: 10 additions & 0 deletions api/src/main/java/jakarta/persistence/EntityManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.CriteriaUpdate;
import jakarta.persistence.criteria.CriteriaDelete;
import jakarta.persistence.sql.ResultSetMapping;

/**
* Interface used to interact with the persistence context.
Expand Down Expand Up @@ -1138,6 +1139,15 @@ void refresh(Object entity,
*/
Query createNativeQuery(String sqlString, String resultSetMapping);

/**
* Create an instance of {@link TypedQuery} for executing
* a native SQL query.
* @param sqlString a native SQL query string
* @param resultSetMapping the result set mapping
* @return the new query instance
*/
<T> TypedQuery<T> createNativeQuery(String sqlString, ResultSetMapping<T> resultSetMapping);

/**
* Create an instance of {@link StoredProcedureQuery} for executing
* a stored procedure in the database.
Expand Down
15 changes: 0 additions & 15 deletions api/src/main/java/jakarta/persistence/EntityResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

package jakarta.persistence;

import java.lang.annotation.Annotation;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
Expand Down Expand Up @@ -91,18 +90,4 @@
* the entity instance.
*/
String discriminatorColumn() default "";

record Map(Class<?> entityClass, String discriminatorColumn, FieldResult[] fields, LockModeType lockMode)
implements EntityResult, SqlResultSetMapping.MappingElement {
Map(Class<?> entityClass, FieldResult... fields) {
this(entityClass, "", fields, LockModeType.NONE);
}
Map(Class<?> entityClass, String discriminatorColumn, FieldResult... fields) {
this(entityClass, discriminatorColumn, fields, LockModeType.NONE);
}
@Override
public Class<? extends Annotation> annotationType() {
return EntityResult.class;
}
}
}
9 changes: 0 additions & 9 deletions api/src/main/java/jakarta/persistence/FieldResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

package jakarta.persistence;

import java.lang.annotation.Annotation;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
Expand Down Expand Up @@ -73,12 +72,4 @@
* the column alias, if applicable.
*/
String column();

record Map(String name, String column)
implements FieldResult {
@Override
public Class<? extends Annotation> annotationType() {
return FieldResult.class;
}
}
}
28 changes: 0 additions & 28 deletions api/src/main/java/jakarta/persistence/SqlResultSetMapping.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,9 @@

package jakarta.persistence;

import java.lang.annotation.Annotation;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import java.lang.reflect.Array;
import java.util.Arrays;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
Expand Down Expand Up @@ -94,31 +91,6 @@
* Specifies the result set mapping to scalar values.
*/
ColumnResult[] columns() default {};

interface MappingElement {}

record Map(String name, EntityResult[] entities, ConstructorResult[] classes, ColumnResult[] columns)
implements SqlResultSetMapping {
@SuppressWarnings("unchecked")
private static <R> R[] newArrayInstance(Class<R> type, int length) {
return (R[]) Array.newInstance(type, length);
}
static <R> R[] extract(Class<R> type, MappingElement[] mappingElements) {
return Arrays.stream(mappingElements)
.filter(type::isInstance)
.toArray(length -> newArrayInstance(type, length));
}
Map(String name, MappingElement... mappings) {
this(name,
extract(EntityResult.class, mappings),
extract(ConstructorResult.class, mappings),
extract(ColumnResult.class, mappings));
}
@Override
public Class<? extends Annotation> annotationType() {
return SqlResultSetMapping.class;
}
}
}


22 changes: 22 additions & 0 deletions api/src/main/java/jakarta/persistence/sql/ColumnMapping.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package jakarta.persistence.sql;

import jakarta.persistence.ColumnResult;

import java.lang.annotation.Annotation;

public record ColumnMapping<T>(String name, Class<T> type)
implements ColumnResult, MappingElement<T> {

public static ColumnMapping<Object> map(String name) {
return new ColumnMapping<>(name, Object.class);
}

public static <T> ColumnMapping<T> map(String name, Class<T> type) {
return new ColumnMapping<>(name, type);
}

@Override
public Class<? extends Annotation> annotationType() {
return ColumnResult.class;
}
}
19 changes: 19 additions & 0 deletions api/src/main/java/jakarta/persistence/sql/ConstructorMapping.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package jakarta.persistence.sql;

import jakarta.persistence.ColumnResult;
import jakarta.persistence.ConstructorResult;

import java.lang.annotation.Annotation;

public record ConstructorMapping<T>(Class<T> targetClass, ColumnResult[] columns)
implements ConstructorResult, MappingElement<T> {

public static <T> ConstructorMapping<T> map(Class<T> targetClass, ColumnResult... columns) {
return new ConstructorMapping<>(targetClass, columns);
}

@Override
public Class<? extends Annotation> annotationType() {
return ConstructorResult.class;
}
}
31 changes: 31 additions & 0 deletions api/src/main/java/jakarta/persistence/sql/EntityMapping.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package jakarta.persistence.sql;

import jakarta.persistence.EntityResult;
import jakarta.persistence.FieldResult;
import jakarta.persistence.LockModeType;

import java.lang.annotation.Annotation;

public record EntityMapping<T>(Class<T> entityClass, LockModeType lockMode, String discriminatorColumn, FieldResult[] fields)
implements EntityResult, MappingElement<T> {

@SafeVarargs
public static <T> EntityMapping<T> map(Class<T> entityClass, FieldMapping<T>... fields) {
return new EntityMapping<>(entityClass, LockModeType.NONE, "", fields);
}

@SafeVarargs
public static <T> EntityMapping<T> map(Class<T> entityClass, String discriminatorColumn, FieldMapping<T>... fields) {
return new EntityMapping<>(entityClass, LockModeType.NONE, discriminatorColumn, fields);
}

@SafeVarargs
public static <T> EntityMapping<T> map(Class<T> entityClass, LockModeType lockMode, String discriminatorColumn, FieldMapping<T>... fields) {
return new EntityMapping<>(entityClass, lockMode, discriminatorColumn, fields);
}

@Override
public Class<? extends Annotation> annotationType() {
return EntityResult.class;
}
}
20 changes: 20 additions & 0 deletions api/src/main/java/jakarta/persistence/sql/FieldMapping.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package jakarta.persistence.sql;

import jakarta.persistence.FieldResult;
import jakarta.persistence.metamodel.SingularAttribute;

import java.lang.annotation.Annotation;

public record FieldMapping<T>(String name, String column)
implements FieldResult {

public static <T> FieldMapping<T> map(SingularAttribute<T,?> attribute, String column) {
return new FieldMapping<>(attribute.getName(), column);
}

@Override
public Class<? extends Annotation> annotationType() {
return FieldResult.class;
}
}

17 changes: 17 additions & 0 deletions api/src/main/java/jakarta/persistence/sql/MappingElement.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package jakarta.persistence.sql;

import java.lang.reflect.Array;
import java.util.Arrays;

public interface MappingElement<T> {

@SuppressWarnings("unchecked")
private static <R> R[] newArrayInstance(Class<R> type, int length) {
return (R[]) Array.newInstance(type, length);
}
static <R> R[] extract(Class<R> type, MappingElement[] mappingElements) {
return Arrays.stream(mappingElements)
.filter(type::isInstance)
.toArray(length -> newArrayInstance(type, length));
}
}
48 changes: 48 additions & 0 deletions api/src/main/java/jakarta/persistence/sql/ResultSetMapping.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package jakarta.persistence.sql;

import jakarta.persistence.ColumnResult;
import jakarta.persistence.ConstructorResult;
import jakarta.persistence.EntityResult;
import jakarta.persistence.SqlResultSetMapping;

import java.lang.annotation.Annotation;

import static jakarta.persistence.sql.MappingElement.extract;

public record ResultSetMapping<T>(String name, EntityResult[] entities, ConstructorResult[] classes, ColumnResult[] columns)
implements SqlResultSetMapping {

public static ResultSetMapping<Object[]> create(MappingElement<?>... mappings) {
return new ResultSetMapping<>("",
extract(EntityResult.class, mappings),
extract(ConstructorResult.class, mappings),
extract(ColumnResult.class, mappings));
}

public static <T> ResultSetMapping<T> create(EntityMapping<T> entityMapping) {
return new ResultSetMapping<>("",
new EntityResult[]{entityMapping},
new ConstructorResult[0],
new ColumnResult[0]);
}

public static <T> ResultSetMapping<T> create(ConstructorMapping<T> constructorMapping) {
return new ResultSetMapping<>("",
new EntityResult[0],
new ConstructorResult[]{constructorMapping},
new ColumnResult[0]);
}

public static <T> ResultSetMapping<T> create(ColumnMapping<T> columnResult) {
return new ResultSetMapping<>("",
new EntityResult[0],
new ConstructorResult[0],
new ColumnResult[]{columnResult});
}

@Override
public Class<? extends Annotation> annotationType() {
return SqlResultSetMapping.class;
}
}

1 change: 1 addition & 0 deletions api/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
exports jakarta.persistence.criteria;
exports jakarta.persistence.metamodel;
exports jakarta.persistence.spi;
exports jakarta.persistence.sql;

uses jakarta.persistence.spi.PersistenceProvider;
}

0 comments on commit f6c5bab

Please sign in to comment.