我有实体Post,PostDetail。 这些是一对一的关系,PostDetail是可选的。
class Post {
@Id
private int id;
@Column
private String title;
@Column
private Strint contents;
@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
private PostDetail postDetail;
}
class PostDetail {
@Id
private int id;
@Column
private boolean duplicated;
@OneToOne
private Post post;
}
public interface PostRepository extends JpaRepository<Post, Integer> {
@Transactional
@Query("SELECT a FROM Post a LEFT JOIN FETCH a.postDetail")
public Page<Post> getAll(Example<Post> example, Pageable pageable);
@Transactional
@Query("SELECT a FROM Post a LEFT JOIN FETCH a.postDetail")
public List<Post> getAll();
}
当应用程序启动时,会发生异常。
引起:org.hibernate.QueryException:查询指定的连接提取,但是获取的关联的所有者在选择列表中不存在...
有什么问题?在查询帖子列表(getAll())时,我试图避免N + 1问题。
抱歉,我修改了我的问题。
两个PostRepository的方法都会出错。
首先getAll()抛出错误&#34;查询指定的连接提取...&#34;
第二个getAll()抛出错误
org.mariadb.jdbc.internal.common.QueryException:未知列&#39; postdetail1_.post_id&#39;在&#39;字段列表&#39;
答案 0 :(得分:2)
如果您正在使用Spring Data JPA,id
中的Post
类型应与ID
中的JpaRepository<T, ID extends Serializable>
一致,只需进行一些修改:
@Entity
@Table(name = "post")
class Post {
@Id
private Integer id;
@Column
private String title;
@Column
private String contents;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "postDetail_id")//assume this is the name
private PostDetail postDetail;
}
而且您不必为getAll()
定义查询,Spring Data JPA为常规查询提供了一些嵌入式实现,只需调用它们:
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {
<S extends T> S save(S entity);
T findOne(ID primaryKey);
Iterable<T> findAll();
Long count();
void delete(T entity);
boolean exists(ID primaryKey);
// … more functionality omitted.
}
所以PostRepository
就像:
public interface PostRepository extends JpaRepository<Post, Integer> {
}
然后你可以在单元测试中测试它:
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTest {
@Autowired
private PostRepository repo;
@Test
public void testFindAll(){
repo.findAll();
}
@Test
public void testFindById(){
repo.findOne(id);
}
}
答案 1 :(得分:2)
如果您想避免1 + N查询问题,可以使用EntityGraph。只需覆盖&#39; findAll&#39;自定义Repo中的方法,并在它们上使用EntityGraph注释,如下所示:
public interface PostRepository extends JpaRepository<Post, Integer> {
@Override
@EntityGraph(attributePaths = {"postDetail"})
Page<Post> findAll(Pageable pageable);
@Override
@EntityGraph(attributePaths = {"postDetail"})
List<Post> findAll();
}