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

Closed Projection does not work with @EntityGraph [DATAJPA-1501]

Open spring-projects-issues opened this issue 6 years ago • 9 comments
trafficstars

asfernandes opened DATAJPA-1501 and commented

I have entities that map others entities using @ManyToOne(fetch = FetchType.LAZY).

// Endereco.java

@Entity
@Table(name = "enderecos")
public class Endereco
{
	private Integer codigo;
	private Cidade cidade;

	@Id
	public Integer getCodigo()
	{
		return super.getCodigo();
	}

	public void setCodigo(Integer codigo)
	{
		this.codigo = codigo;
	}

	@ManyToOne(optional = false, fetch = FetchType.LAZY)
	@JoinColumn(name = "cid_codigo")
	public Cidade getCidade()
	{
		return cidade;
	}

	public void setCidade(Cidade cidade)
	{
		this.cidade = cidade;
	}
}
// Cidade.java

@Entity
@Table(name = "cidades")
public class Cidade
{
	private Integer codigo;
	private String nome;

	@Id
	public Integer getCodigo()
	{
		return super.getCodigo();
	}

	public void setCodigo(Integer codigo)
	{
		this.codigo = codigo;
	}

	public String getNome()
	{
		return nome;
	}

	public void setNome(String nome)
	{
		this.nome = nome;
	}
}

 

Then I have created a repository interface with a method using @EntityGraph:

@EntityGraph(type = EntityGraphType.FETCH,
	attributePaths = {
		"cidade"
	}
)
<T> List<T> findFetchCidade(Class<T> type);

 

And created projection interfaces:

public interface EnderecoProjection
{
	Integer getCodigo();
	CidadeProjection getCidade();

	/*
	@Value("#{target.codigo}")
	Integer getSomething();
	*/
}

public interface CidadeProjection
{
	Integer getCodigo();
	String getNome();
}

 

When I use findFetchCidade passing a EnderecoProjection, I have this error:

org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list

 

Note that if I uncomment the @Value annotation, the projection becomes opened and then no error happens


Affects: 2.1.4 (Lovelace SR4)

spring-projects-issues avatar Jan 29 '19 16:01 spring-projects-issues

Oliver Drotbohm commented

This looks like a wild mixture of entity graphs and projections, which we didn't quite anticipate before. What's the reason you need to mix those up? EnderecoProjection.getSomething() could just be a default method, couldn't it?

spring-projects-issues avatar Jan 29 '19 16:01 spring-projects-issues

asfernandes commented

If the projection is used directly (no generics) in findFetchCidade, the same thing happens

spring-projects-issues avatar Jan 29 '19 16:01 spring-projects-issues

asfernandes commented

Oliver Drotbohm I don't need the getSomething. It's used just to make the thing work. My real case is some nesting of projections (Endereco -> Cidade -> Estado -> Pais), that I need some fields of each, and I want to have LAZY in the entities

spring-projects-issues avatar Jan 29 '19 16:01 spring-projects-issues

asfernandes commented

Oliver Drotbohm you say the problem is the mixture of entity graphs and projections, but for me the problem seems to be about nested projections not creating a JPQL selecting the fetched entities. At least that seems to be what the error says.

It's weird because nested projections is documented as something supported

spring-projects-issues avatar Jan 29 '19 17:01 spring-projects-issues

Just found this after logging my issue (https://github.com/spring-projects/spring-data-jpa/issues/2709)

SchlauFuchs avatar Nov 22 '22 23:11 SchlauFuchs

This repo demonstrates that entity graph is ignored in Spring-Data when it is used in combination with closed-projection:

https://github.com/Eng-Fouad/spring-closed-projection-entity-graph

Eng-Fouad avatar Aug 17 '23 05:08 Eng-Fouad

As a workaround:

@EntityGraph(value = "SomeEntityGraph")
EntityClass queryById(int id);
EntityClass entity = entityRepo.queryById(1);
EntityProjection entityProjection = new CollectionAwareProjectionFactory().createProjection(EntityProjection.class, entity);

However, the generated query will include all columns in SELECT clause, as the return type is EntityClass not EntityProjection.

Eng-Fouad avatar Aug 18 '23 07:08 Eng-Fouad

Any updates regarding this issue? @odrotbohm @mp911de @schauder @gregturn @christophstrobl

Eng-Fouad avatar Aug 18 '23 08:08 Eng-Fouad

The actual question is: What should happen if a closed projection and an @EntityGraph are defined? Do we ignore the entity graph or do we ignore the reduction of columns as per the projection definition?

mp911de avatar Aug 18 '23 11:08 mp911de