HHH-13620, HHH-13869 fix handling of nested embeddable access type in Processor
Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
parent
ef1cbf589d
commit
9fbdafe318
|
@ -518,7 +518,7 @@ public class HibernateProcessor extends AbstractProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isEntityOrEmbeddable(Element element) {
|
private static boolean isEntityOrEmbeddable(Element element) {
|
||||||
return containsAnnotation(
|
return hasAnnotation(
|
||||||
element,
|
element,
|
||||||
ENTITY,
|
ENTITY,
|
||||||
MAPPED_SUPERCLASS,
|
MAPPED_SUPERCLASS,
|
||||||
|
@ -550,7 +550,7 @@ public class HibernateProcessor extends AbstractProcessor {
|
||||||
|
|
||||||
private void handleRootElementAnnotationMirrors(final Element element) {
|
private void handleRootElementAnnotationMirrors(final Element element) {
|
||||||
if ( isClassOrRecordType( element ) ) {
|
if ( isClassOrRecordType( element ) ) {
|
||||||
if ( hasAnnotation( element, ENTITY, MAPPED_SUPERCLASS, EMBEDDABLE ) ) {
|
if ( isEntityOrEmbeddable( element ) ) {
|
||||||
final TypeElement typeElement = (TypeElement) element;
|
final TypeElement typeElement = (TypeElement) element;
|
||||||
indexEntityName( typeElement );
|
indexEntityName( typeElement );
|
||||||
indexEnumFields( typeElement );
|
indexEnumFields( typeElement );
|
||||||
|
|
|
@ -39,6 +39,7 @@ import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import static java.beans.Introspector.decapitalize;
|
import static java.beans.Introspector.decapitalize;
|
||||||
|
import static org.hibernate.processor.util.AccessTypeInformation.DEFAULT_ACCESS_TYPE;
|
||||||
import static org.hibernate.processor.util.Constants.ACCESS;
|
import static org.hibernate.processor.util.Constants.ACCESS;
|
||||||
import static org.hibernate.processor.util.Constants.BASIC;
|
import static org.hibernate.processor.util.Constants.BASIC;
|
||||||
import static org.hibernate.processor.util.Constants.ELEMENT_COLLECTION;
|
import static org.hibernate.processor.util.Constants.ELEMENT_COLLECTION;
|
||||||
|
@ -70,9 +71,6 @@ public final class TypeUtils {
|
||||||
private static final Map<TypeKind, String> PRIMITIVE_WRAPPERS = new HashMap<>();
|
private static final Map<TypeKind, String> PRIMITIVE_WRAPPERS = new HashMap<>();
|
||||||
private static final Map<TypeKind, String> PRIMITIVES = new HashMap<>();
|
private static final Map<TypeKind, String> PRIMITIVES = new HashMap<>();
|
||||||
|
|
||||||
private static final String PROPERTY = AccessType.PROPERTY.toString();
|
|
||||||
private static final String FIELD = AccessType.FIELD.toString();
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
PRIMITIVE_WRAPPERS.put( TypeKind.CHAR, "Character" );
|
PRIMITIVE_WRAPPERS.put( TypeKind.CHAR, "Character" );
|
||||||
|
|
||||||
|
@ -320,8 +318,7 @@ public final class TypeUtils {
|
||||||
// if we end up here we need to recursively look for superclasses
|
// if we end up here we need to recursively look for superclasses
|
||||||
AccessType newDefaultAccessType = getDefaultAccessForHierarchy( searchedElement, context );
|
AccessType newDefaultAccessType = getDefaultAccessForHierarchy( searchedElement, context );
|
||||||
if ( newDefaultAccessType == null ) {
|
if ( newDefaultAccessType == null ) {
|
||||||
//TODO: this default is arbitrary and very questionable!
|
newDefaultAccessType = DEFAULT_ACCESS_TYPE;
|
||||||
newDefaultAccessType = AccessType.PROPERTY;
|
|
||||||
}
|
}
|
||||||
final AccessTypeInformation newAccessTypeInfo =
|
final AccessTypeInformation newAccessTypeInfo =
|
||||||
new AccessTypeInformation( qualifiedName, null, newDefaultAccessType );
|
new AccessTypeInformation( qualifiedName, null, newDefaultAccessType );
|
||||||
|
@ -369,6 +366,8 @@ public final class TypeUtils {
|
||||||
final AccessTypeInformation newAccessTypeInfo =
|
final AccessTypeInformation newAccessTypeInfo =
|
||||||
new AccessTypeInformation( embeddedClassName, null, defaultAccessType );
|
new AccessTypeInformation( embeddedClassName, null, defaultAccessType );
|
||||||
context.addAccessTypeInformation( embeddedClassName, newAccessTypeInfo );
|
context.addAccessTypeInformation( embeddedClassName, newAccessTypeInfo );
|
||||||
|
final TypeElement typeElement = context.getElementUtils().getTypeElement(embeddedClassName);
|
||||||
|
updateEmbeddableAccessType( typeElement, context, defaultAccessType );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
accessTypeInfo.setDefaultAccessType( defaultAccessType );
|
accessTypeInfo.setDefaultAccessType( defaultAccessType );
|
||||||
|
@ -479,10 +478,10 @@ public final class TypeUtils {
|
||||||
if ( accessType != null ) {
|
if ( accessType != null ) {
|
||||||
final VariableElement enumValue = (VariableElement) accessType.getValue();
|
final VariableElement enumValue = (VariableElement) accessType.getValue();
|
||||||
final Name enumValueName = enumValue.getSimpleName();
|
final Name enumValueName = enumValue.getSimpleName();
|
||||||
if ( enumValueName.contentEquals(PROPERTY) ) {
|
if ( enumValueName.contentEquals(AccessType.PROPERTY.name()) ) {
|
||||||
return AccessType.PROPERTY;
|
return AccessType.PROPERTY;
|
||||||
}
|
}
|
||||||
else if ( enumValueName.contentEquals(FIELD) ) {
|
else if ( enumValueName.contentEquals(AccessType.FIELD.name()) ) {
|
||||||
return AccessType.FIELD;
|
return AccessType.FIELD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
package org.hibernate.processor.test.embeddable.nested.field;
|
||||||
|
|
||||||
|
import jakarta.persistence.Embeddable;
|
||||||
|
import org.hibernate.processor.test.embeddable.nested.property.Postcode;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public final class Address {
|
||||||
|
private String street;
|
||||||
|
private String city;
|
||||||
|
private org.hibernate.processor.test.embeddable.nested.property.Postcode postcode;
|
||||||
|
|
||||||
|
|
||||||
|
public String getStreet() {
|
||||||
|
return street;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCity() {
|
||||||
|
return city;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Postcode getPostcode() {
|
||||||
|
return postcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == this) return true;
|
||||||
|
if (obj == null || obj.getClass() != this.getClass()) return false;
|
||||||
|
var that = (Address) obj;
|
||||||
|
return Objects.equals(this.street, that.street) &&
|
||||||
|
Objects.equals(this.city, that.city) &&
|
||||||
|
Objects.equals(this.postcode, that.postcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(street, city, postcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Address[" +
|
||||||
|
"street=" + street + ", " +
|
||||||
|
"city=" + city + ", " +
|
||||||
|
"postcode=" + postcode + ']';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package org.hibernate.processor.test.embeddable.nested.field;
|
||||||
|
|
||||||
|
import jakarta.persistence.Basic;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Author {
|
||||||
|
@Id
|
||||||
|
String ssn;
|
||||||
|
|
||||||
|
@Basic(optional = false)
|
||||||
|
String name;
|
||||||
|
|
||||||
|
Address address;
|
||||||
|
|
||||||
|
Boolean deceased;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* 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.processor.test.embeddable.nested.field;
|
||||||
|
|
||||||
|
import org.hibernate.processor.test.util.CompilationTest;
|
||||||
|
import org.hibernate.processor.test.util.WithClasses;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hibernate.processor.test.util.TestUtil.assertAttributeTypeInMetaModelFor;
|
||||||
|
|
||||||
|
public class NestedEmbeddableTest extends CompilationTest {
|
||||||
|
@Test
|
||||||
|
@WithClasses({ Author.class, Address.class, Postcode.class })
|
||||||
|
public void testCorrectAccessTypeUsedForEmbeddable() {
|
||||||
|
assertAttributeTypeInMetaModelFor(
|
||||||
|
Address.class,
|
||||||
|
"city",
|
||||||
|
String.class,
|
||||||
|
"city should be String"
|
||||||
|
);
|
||||||
|
assertAttributeTypeInMetaModelFor(
|
||||||
|
Postcode.class,
|
||||||
|
"zip",
|
||||||
|
String.class,
|
||||||
|
"zip should be String"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package org.hibernate.processor.test.embeddable.nested.field;
|
||||||
|
|
||||||
|
import jakarta.persistence.Embeddable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public final class Postcode {
|
||||||
|
private String zip;
|
||||||
|
private String plusFour;
|
||||||
|
|
||||||
|
public String getZip() {
|
||||||
|
return zip;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPlusFour() {
|
||||||
|
return plusFour;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == this) return true;
|
||||||
|
if (obj == null || obj.getClass() != this.getClass()) return false;
|
||||||
|
var that = (Postcode) obj;
|
||||||
|
return Objects.equals(this.zip, that.zip) &&
|
||||||
|
Objects.equals(this.plusFour, that.plusFour);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(zip, plusFour);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Postcode[" +
|
||||||
|
"zip=" + zip + ", " +
|
||||||
|
"plusFour=" + plusFour + ']';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package org.hibernate.processor.test.embeddable.nested.property;
|
||||||
|
|
||||||
|
import jakarta.persistence.Embeddable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public final class Address {
|
||||||
|
private String street;
|
||||||
|
private String city;
|
||||||
|
private Postcode postcode;
|
||||||
|
|
||||||
|
|
||||||
|
public String getStreet() {
|
||||||
|
return street;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCity() {
|
||||||
|
return city;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Postcode getPostcode() {
|
||||||
|
return postcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == this) return true;
|
||||||
|
if (obj == null || obj.getClass() != this.getClass()) return false;
|
||||||
|
var that = (Address) obj;
|
||||||
|
return Objects.equals(this.street, that.street) &&
|
||||||
|
Objects.equals(this.city, that.city) &&
|
||||||
|
Objects.equals(this.postcode, that.postcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(street, city, postcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Address[" +
|
||||||
|
"street=" + street + ", " +
|
||||||
|
"city=" + city + ", " +
|
||||||
|
"postcode=" + postcode + ']';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package org.hibernate.processor.test.embeddable.nested.property;
|
||||||
|
|
||||||
|
import jakarta.persistence.Basic;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Author {
|
||||||
|
String ssn;
|
||||||
|
|
||||||
|
String name;
|
||||||
|
|
||||||
|
Address address;
|
||||||
|
|
||||||
|
Boolean deceased;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
public String getSsn() {
|
||||||
|
return ssn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSsn(String ssn) {
|
||||||
|
this.ssn = ssn;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Basic(optional = false)
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress(Address address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getDeceased() {
|
||||||
|
return deceased;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeceased(Boolean deceased) {
|
||||||
|
this.deceased = deceased;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* 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.processor.test.embeddable.nested.property;
|
||||||
|
|
||||||
|
import org.hibernate.processor.test.util.CompilationTest;
|
||||||
|
import org.hibernate.processor.test.util.WithClasses;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hibernate.processor.test.util.TestUtil.assertAttributeTypeInMetaModelFor;
|
||||||
|
|
||||||
|
public class NestedEmbeddableTest extends CompilationTest {
|
||||||
|
@Test
|
||||||
|
@WithClasses({ Author.class, Address.class, Postcode.class })
|
||||||
|
public void testCorrectAccessTypeUsedForEmbeddable() {
|
||||||
|
assertAttributeTypeInMetaModelFor(
|
||||||
|
Address.class,
|
||||||
|
"city",
|
||||||
|
String.class,
|
||||||
|
"city should be String"
|
||||||
|
);
|
||||||
|
assertAttributeTypeInMetaModelFor(
|
||||||
|
Postcode.class,
|
||||||
|
"zip",
|
||||||
|
String.class,
|
||||||
|
"zip should be String"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package org.hibernate.processor.test.embeddable.nested.property;
|
||||||
|
|
||||||
|
import jakarta.persistence.Embeddable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public final class Postcode {
|
||||||
|
private String zip;
|
||||||
|
private String plusFour;
|
||||||
|
|
||||||
|
public String getZip() {
|
||||||
|
return zip;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPlusFour() {
|
||||||
|
return plusFour;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == this) return true;
|
||||||
|
if (obj == null || obj.getClass() != this.getClass()) return false;
|
||||||
|
var that = (Postcode) obj;
|
||||||
|
return Objects.equals(this.zip, that.zip) &&
|
||||||
|
Objects.equals(this.plusFour, that.plusFour);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(zip, plusFour);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Postcode[" +
|
||||||
|
"zip=" + zip + ", " +
|
||||||
|
"plusFour=" + plusFour + ']';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue