JpaRepository 将自定义接口错误为 属性
JpaRepository mistakes custom interface as property
对于一般的springJpaRepository DAO(nospring-boot),如果接口扩展自定义接口,spring会出错接口方法作为对象的属性。
例如
interface ILocalDateTime {
fun getLocalDateTime() : LocalDateTime
}
interface UserDaoCustom : ILocalDateTime {
// query functions skipped
}
interface UserDao : JpaRepository<User, Long>, UserDaoCustom
class UserImpl : UserDaoCustom {
@PersistenceContext
private lateinit var em: EntityManager
override fun getLocalDateTime(): LocalDateTime {
return LocalDateTime.now()
}
// query functions skipped
}
这是一个简化的 UserDao
。 UserDaoCustom
extends ILocalDateTime
其中包含一个方法 getLocalDateTime
.
注意:localDateTime
不是 User
的字段。
在运行时,JpaRepository
会将getLocalDateTime
(或localDateTime
?)误认为是User
的字段,并抛出这样的异常:
Caused by: org.springframework.data.repository.query.QueryCreationException:
Could not create query for public abstract java.time.LocalDateTime foo.ILocalDateTime.getLocalDateTime()!
Reason: Failed to create query for method public abstract java.time.LocalDateTime foo.ILocalDateTime.getLocalDateTime()!
No property getLocalDateTime found for type User!;
nested exception is java.lang.IllegalArgumentException:
Failed to create query for method public abstract java.time.LocalDateTime foo.ILocalDateTime.getLocalDateTime()!
No property getLocalDateTime found for type User!
环境:
Kotlin 1.6.20
Spring 5.3.19
spring-data-jpa 2.5.11
如何解决这个问题? (能够或不能修改ILocalDateTime
的代码)
谢谢。
我认为这是关于命名以及如何 Spring 获取存储库扩展的实现。
TLDR;
将您的实施名称从 UserImpl
更改为 UserDaoCustomImpl
.
我检查了一个类似的设置,使用你的命名失败并出现完全相同的错误,但将其命名为“正确”使其按预期工作
public interface ILocalDateTime {
LocalDateTime getLocalDateTime();
}
@Repository
public interface UserDao extends UserDaoCustom, JpaRepository<User, Long> {
}
public interface UserDaoCustom extends ILocalDateTime{
}
@Repository
public class UserDaoCustomImpl implements UserDaoCustom {
@Override
public LocalDateTime getLocalDateTime() {
return LocalDateTime.now();
}
}
和测试
@ExtendWith(SpringExtension.class)
@DataJpaTest
class UserRepositoryTest {
@Autowired
private UserDao userDao;
@Test
public void savesUser() {
userDao.save(new User());
}
@Test
public void bazzinga() {
assert userDao.getLocalDateTime() != null;
System.out.println("Bazzinga!"+userDao.getLocalDateTime());
}
}
产量
对于一般的springJpaRepository DAO(nospring-boot),如果接口扩展自定义接口,spring会出错接口方法作为对象的属性。
例如
interface ILocalDateTime {
fun getLocalDateTime() : LocalDateTime
}
interface UserDaoCustom : ILocalDateTime {
// query functions skipped
}
interface UserDao : JpaRepository<User, Long>, UserDaoCustom
class UserImpl : UserDaoCustom {
@PersistenceContext
private lateinit var em: EntityManager
override fun getLocalDateTime(): LocalDateTime {
return LocalDateTime.now()
}
// query functions skipped
}
这是一个简化的 UserDao
。 UserDaoCustom
extends ILocalDateTime
其中包含一个方法 getLocalDateTime
.
注意:localDateTime
不是 User
的字段。
在运行时,JpaRepository
会将getLocalDateTime
(或localDateTime
?)误认为是User
的字段,并抛出这样的异常:
Caused by: org.springframework.data.repository.query.QueryCreationException:
Could not create query for public abstract java.time.LocalDateTime foo.ILocalDateTime.getLocalDateTime()!
Reason: Failed to create query for method public abstract java.time.LocalDateTime foo.ILocalDateTime.getLocalDateTime()!
No property getLocalDateTime found for type User!;
nested exception is java.lang.IllegalArgumentException:
Failed to create query for method public abstract java.time.LocalDateTime foo.ILocalDateTime.getLocalDateTime()!
No property getLocalDateTime found for type User!
环境:
Kotlin 1.6.20
Spring 5.3.19
spring-data-jpa 2.5.11
如何解决这个问题? (能够或不能修改ILocalDateTime
的代码)
谢谢。
我认为这是关于命名以及如何 Spring 获取存储库扩展的实现。
TLDR;
将您的实施名称从 UserImpl
更改为 UserDaoCustomImpl
.
我检查了一个类似的设置,使用你的命名失败并出现完全相同的错误,但将其命名为“正确”使其按预期工作
public interface ILocalDateTime {
LocalDateTime getLocalDateTime();
}
@Repository
public interface UserDao extends UserDaoCustom, JpaRepository<User, Long> {
}
public interface UserDaoCustom extends ILocalDateTime{
}
@Repository
public class UserDaoCustomImpl implements UserDaoCustom {
@Override
public LocalDateTime getLocalDateTime() {
return LocalDateTime.now();
}
}
和测试
@ExtendWith(SpringExtension.class)
@DataJpaTest
class UserRepositoryTest {
@Autowired
private UserDao userDao;
@Test
public void savesUser() {
userDao.save(new User());
}
@Test
public void bazzinga() {
assert userDao.getLocalDateTime() != null;
System.out.println("Bazzinga!"+userDao.getLocalDateTime());
}
}
产量