Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate UserType implementations to hibernate 6 #40

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ description = "Hibernate ORM Migration"
recipeDependencies {
parserClasspath("jakarta.persistence:jakarta.persistence-api:latest.release")
parserClasspath("org.hibernate.orm:hibernate-core:6.5.1.Final")
parserClasspath("org.hibernate.orm:hibernate-core:5.6.15.Final")
}

val rewriteVersion = rewriteRecipe.rewriteVersion.get()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public J.Annotation visitAnnotation(J.Annotation annotation, ExecutionContext ct
String converterFQN = String.format("org.hibernate.type.%s", converterName);

ann = JavaTemplate.builder(String.format("@Convert(converter = %s.class)", converterName))
.javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "hibernate-core", "jakarta.persistence-api"))
.javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "hibernate-core-6+", "jakarta.persistence-api"))
.imports(converterFQN, "jakarta.persistence.Convert")
.contextSensitive()
.build().apply(getCursor(), ann.getCoordinates().replace());
Expand Down
252 changes: 252 additions & 0 deletions src/main/java/org/openrewrite/hibernate/MigrateUserType.java

Large diffs are not rendered by default.

Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class MigrateBooleanMappingsTest implements RewriteTest {
public void defaults(RecipeSpec spec) {
spec.recipe(new MigrateBooleanMappings())
.parser(JavaParser.fromJavaVersion()
.classpathFromResources(new InMemoryExecutionContext(),"hibernate-core", "jakarta.persistence-api")
.classpathFromResources(new InMemoryExecutionContext(),"hibernate-core-6+", "jakarta.persistence-api")
);
}

Expand Down
199 changes: 199 additions & 0 deletions src/test/java/org/openrewrite/hibernate/MigrateUserTypeTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
/*
* Copyright 2024 the original author or authors.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openrewrite.hibernate;

import org.junit.jupiter.api.Test;
import org.openrewrite.DocumentExample;
import org.openrewrite.InMemoryExecutionContext;
import org.openrewrite.java.JavaParser;
import org.openrewrite.test.RecipeSpec;
import org.openrewrite.test.RewriteTest;

import static org.openrewrite.java.Assertions.java;

class MigrateUserTypeTest implements RewriteTest {

@Override
public void defaults(RecipeSpec spec) {
spec.recipe(new MigrateUserType())
.parser(JavaParser.fromJavaVersion()
.classpathFromResources(new InMemoryExecutionContext(), "hibernate-core-5+")
);
}

@Test
@DocumentExample
void shouldMigrateUserType() {
//language=java
rewriteRun(
spec -> spec.expectedCyclesThatMakeChanges(2),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we fix the recipe such that we don't need this escape hatch, as we'd love to drop that in a next major version. Did you explore why this was needed in the first place?

Suggested change
spec -> spec.expectedCyclesThatMakeChanges(2),

java(
"""
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.UserType;
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Objects;
public class BigDecimalAsString implements UserType {
@Override
public int[] sqlTypes() {
return new int[]{Types.VARCHAR};
}
@Override
public Class returnedClass() {
return BigDecimal.class;
}
@Override
public boolean equals(Object x, Object y) {
return Objects.equals(x, y);
}
@Override
public int hashCode(Object x) {
return Objects.hashCode(x);
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner) throws SQLException {
String string = rs.getString(names[0]);
return string == null || rs.wasNull() ? null : new BigDecimal(string);
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor session) throws SQLException {
if (value == null) {
st.setNull(index, Types.VARCHAR);
} else {
st.setString(index, value.toString());
}
}
@Override
public Object deepCopy(Object value) {
return value;
}
@Override
public boolean isMutable() {
return false;
}
@Override
public Serializable disassemble(Object value) {
return (BigDecimal) value;
}
@Override
public Object assemble(Serializable cached, Object owner) {
return cached;
}
@Override
public Object replace(Object original, Object target, Object owner) {
return original;
}
}
""",
"""
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.UserType;
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Objects;
public class BigDecimalAsString implements UserType<BigDecimal> {
@Override
public int getSqlType() {
return Types.VARCHAR;
}
@Override
public Class<BigDecimal> returnedClass() {
return BigDecimal.class;
}
@Override
public boolean equals(BigDecimal x, BigDecimal y) {
return Objects.equals(x, y);
}
@Override
public int hashCode(BigDecimal x) {
return Objects.hashCode(x);
}
@Override
public BigDecimal nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException {
String string = rs.getString(position);
return string == null || rs.wasNull() ? null : new BigDecimal(string);
}
@Override
public void nullSafeSet(PreparedStatement st, BigDecimal value, int index, SharedSessionContractImplementor session) throws SQLException {
if (value == null) {
st.setNull(index, Types.VARCHAR);
} else {
st.setString(index, value.toString());
}
}
@Override
public BigDecimal deepCopy(BigDecimal value) {
return value;
}
@Override
public boolean isMutable() {
return false;
}
@Override
public Serializable disassemble(BigDecimal value) {
return value;
}
@Override
public BigDecimal assemble(Serializable cached, Object owner) {
return (BigDecimal) cached;
}
@Override
public BigDecimal replace(BigDecimal original, BigDecimal target, Object owner) {
return original;
}
}
"""
)
);
}
}
Laurens-W marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class ReplaceLazyCollectionAnnotationTest implements RewriteTest {
public void defaults(RecipeSpec spec) {
spec.recipe(new ReplaceLazyCollectionAnnotation())
.parser(JavaParser.fromJavaVersion()
.classpathFromResources(new InMemoryExecutionContext(), "hibernate-core", "jakarta.persistence-api")
.classpathFromResources(new InMemoryExecutionContext(), "hibernate-core-6+", "jakarta.persistence-api")
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
class TypeAnnotationParameterTest implements RewriteTest {
@Override
public void defaults(RecipeSpec spec) {
spec.recipe(new TypeAnnotationParameter()).parser(JavaParser.fromJavaVersion().classpathFromResources(new InMemoryExecutionContext(), "hibernate-core"));
spec.recipe(new TypeAnnotationParameter()).parser(JavaParser.fromJavaVersion().classpathFromResources(new InMemoryExecutionContext(), "hibernate-core-6+"));
}

@DocumentExample
Expand Down