Fallback to Path.getModel() if ManagedType information was erased.
ManagedType information may be erased if the attribute is declared as generic - With Hibernate 6.x for example an IllegalArgumentException is thrown. java.lang.IllegalArgumentException: Unable to locate Attribute with the given name [name] on this ManagedType [java.lang.Object] at o.h.m.model.domain.AbstractManagedType.checkNotNull(AbstractManagedType.java:225) ~[hibernate-core-6.3.1.Final.jar:6.3.1.Final] Resolves: #3274 Original Pull Request: #3375
This commit is contained in:
committed by
Christoph Strobl
parent
c78483ed8d
commit
48e7b62579
@@ -92,6 +92,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Donghun Shin
|
||||
* @author Pranav HS
|
||||
* @author Eduard Dudar
|
||||
* @author Yanming Zhou
|
||||
*/
|
||||
public abstract class QueryUtils {
|
||||
|
||||
@@ -844,7 +845,15 @@ public abstract class QueryUtils {
|
||||
managedType = (ManagedType<?>) ((SingularAttribute<?, ?>) model).getType();
|
||||
}
|
||||
if (managedType != null) {
|
||||
propertyPathModel = (Bindable<?>) managedType.getAttribute(segment);
|
||||
try {
|
||||
propertyPathModel = (Bindable<?>) managedType.getAttribute(segment);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// ManagedType may be erased type for some vendor if the attribute is declared as generic
|
||||
// see: https://hibernate.atlassian.net/browse/HHH-16144
|
||||
// see: https://github.com/hibernate/hibernate-orm/pull/7630
|
||||
// see: https://github.com/jakartaee/persistence/issues/562
|
||||
propertyPathModel = from.get(segment).getModel();
|
||||
}
|
||||
} else {
|
||||
propertyPathModel = from.get(segment).getModel();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2008-2024 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.springframework.data.jpa.domain.sample;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
/**
|
||||
* @author Yanming Zhou
|
||||
*/
|
||||
@Entity
|
||||
public class Book extends OwnerContainer<Owner> {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2008-2024 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.springframework.data.jpa.domain.sample;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
/**
|
||||
* @author Yanming Zhou
|
||||
*/
|
||||
@Entity
|
||||
public class Owner extends AbstractPersistable<Long> {
|
||||
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2008-2024 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.springframework.data.jpa.domain.sample;
|
||||
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
|
||||
/**
|
||||
* @author Yanming Zhou
|
||||
*/
|
||||
@MappedSuperclass
|
||||
public class OwnerContainer<T> {
|
||||
|
||||
@ManyToOne
|
||||
T owner;
|
||||
|
||||
public T getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public void setOwner(T owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2014-2024 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.springframework.data.jpa.repository.generics;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.jpa.domain.sample.Book;
|
||||
import org.springframework.data.jpa.domain.sample.Owner;
|
||||
import org.springframework.data.jpa.repository.sample.BookRepository;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Yanming Zhou
|
||||
*/
|
||||
@Transactional
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration({ "classpath:eclipselink.xml", "classpath:config/namespace-application-context.xml" })
|
||||
class EclipseLinkGenericsIntegrationTests extends GenericsIntegrationTests {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2014-2024 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.springframework.data.jpa.repository.generics;
|
||||
|
||||
import jakarta.persistence.EntityManager;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
import org.springframework.data.jpa.domain.sample.Book;
|
||||
import org.springframework.data.jpa.domain.sample.CustomAbstractPersistable;
|
||||
import org.springframework.data.jpa.domain.sample.Owner;
|
||||
import org.springframework.data.jpa.repository.sample.BookRepository;
|
||||
import org.springframework.data.jpa.repository.sample.CustomAbstractPersistableRepository;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Yanming Zhou
|
||||
*/
|
||||
@Transactional
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration(locations = { "classpath:config/namespace-autoconfig-context.xml" })
|
||||
class GenericsIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
BookRepository repository;
|
||||
|
||||
@Autowired
|
||||
EntityManager entityManager;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
Owner owner = new Owner();
|
||||
owner.setName("owner");
|
||||
entityManager.persist(owner);
|
||||
Book book = new Book();
|
||||
book.setOwner(owner);
|
||||
entityManager.persist(book);
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAllByGenericAssociationProperty() {
|
||||
assertThat(repository.findAllByOwnerName("owner")).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2014-2024 the original author or authors.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.springframework.data.jpa.repository.sample;
|
||||
|
||||
import org.springframework.data.jpa.domain.sample.Book;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Yanming Zhou
|
||||
*/
|
||||
public interface BookRepository extends JpaRepository<Book, Long> {
|
||||
|
||||
List<Book> findAllByOwnerName(String ownerName);
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
<class>org.springframework.data.jpa.domain.sample.AuditableUser</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.AuditableEntity</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.AuditableEmbeddable</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.Book</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.Category</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.Child</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.ConcreteType1</class>
|
||||
@@ -33,6 +34,7 @@
|
||||
<class>org.springframework.data.jpa.domain.sample.MailSender</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.MailUser</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.Order</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.Owner</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.Parent</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.PersistableWithIdClass</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.PersistableWithSingleIdClass
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<class>org.springframework.data.jpa.domain.sample.AuditableUser</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.AuditableEntity</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.AuditableEmbeddable</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.Book</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.Category</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.CustomAbstractPersistable</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.EntityWithAssignedId</class>
|
||||
@@ -20,6 +21,7 @@
|
||||
<class>org.springframework.data.jpa.domain.sample.Role</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.Site</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.SpecialUser</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.Owner</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.User</class>
|
||||
<class>org.springframework.data.jpa.domain.sample.Dummy</class>
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
|
||||
Reference in New Issue
Block a user