spring-data-jpa icon indicating copy to clipboard operation
spring-data-jpa copied to clipboard

OneToOne mapping is not projected

Open joheb-mohemian opened this issue 3 years ago • 5 comments

Hi,

I've set up an example project here that showcases what seems to be a bug in Spring Data projections: https://github.com/joheb-mohemian/gs-accessing-data-jpa/tree/primary-key-join-column-projection-bug/complete

I have a Customer entity that has a OneToOne mapping to an Address entity:

@Entity
public class Customer {

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Long id;
	private String firstName;
	private String lastName;

	@OneToOne(mappedBy = "customer", cascade = CascadeType.ALL)
	@PrimaryKeyJoinColumn
	private Address address;

//...
}
@Entity
public class Address {

	@Id
	@Column(name = "customer_id")
	private Long id;

	@OneToOne
	@MapsId
	@JoinColumn(name = "customer_id")
	private Customer customer;

	private String street;
//...
}

Then there are simple projection interfaces:

public interface CustomerProjection {

	String getFirstName();

	String getLastName();

	AddressProjection getAddress();
}
public interface AddressProjection {

    String getStreet();
}

But when I try to fetch a projected entity from a repository method like this one:

public interface CustomerRepository extends CrudRepository<Customer, Long> {
        //...
	<T> T findById(long id, Class<T> type);
}

, getAddress() on the projection will be null, whereas getAddress() when fetching the entity type is populated correctly. Of these two unit tests, only testEntityWithOneToOne()will be successful:

        @BeforeEach
	void setUpData() {
		customer = new Customer("first", "last");
		Address address = new Address(customer, "street");
		customer.setAddress(address);
		entityManager.persist(address);
		entityManager.persist(customer);
	}

	@Test
	void testEntityWithOneToOne() {
		Customer customerEntity = customers.findById(customer.getId().longValue());
		assertThat(customerEntity.getAddress()).isNotNull();
	}

	@Test
	void testProjectionWithOneToOne() {
		CustomerProjection customerProjection = customers.findById(customer.getId(), CustomerProjection.class);
		assertThat(customerProjection.getAddress()).isNotNull();
	}

What's the problem here? Thanks for looking into it.

joheb-mohemian avatar Dec 01 '21 06:12 joheb-mohemian

Posted a StackOverflow question with about the same content, hoping that somebody might find out what's wrong or confirm that this might be a bug: https://stackoverflow.com/q/70213967/15583224

joheb-mohemian avatar Dec 03 '21 12:12 joheb-mohemian

This seems to be a Hibernate issue. Formulating a CriteriaQuery with type Tuple and selecting the Address it gets returned as null. See the tests I added to your example: https://github.com/schauder/issue-SD-JPA-2369-projection-of-one-to-one

Could you create an issue with Hibernate?

Side note: We don't support nest projections yet so you only can return an Address

schauder avatar Dec 03 '21 15:12 schauder

@schauder Thanks for looking into it and finding out the root cause.

Example 81 in the official documentation seems to suggest that nested projections are indeed supported.

interface PersonSummary {

  String getFirstname();
  String getLastname();
  AddressSummary getAddress();

  interface AddressSummary {
    String getCity();
  }
}

This baeldung article states that nested projections (recursive projections) only work when traversing from the owning side. That makes me think that the Hibernate bug you found might be a known limitation, but I will go ahead and create an issue there. Mind if I reference your repository with the failing tuple query?

joheb-mohemian avatar Dec 06 '21 08:12 joheb-mohemian

Mind if I reference your repository with the failing tuple query?

I don't mind at all. But be aware that the Hibernate team isn't to fond of reproducers involving Spring since they'd have to make sure that the problem doesn't come from something Spring is doing.

schauder avatar Dec 06 '21 09:12 schauder

created an issue with Hibernate here https://hibernate.atlassian.net/browse/HHH-14955

joheb-mohemian avatar Dec 06 '21 11:12 joheb-mohemian