Myt*_*tap 6 java orm spring hibernate spring-data-jpa
在应用程序运行时出错
This class [class com.socnetw.socnetw.model.Relationship] does not define an IdClass
。当我使用 EntityManager 时,一切都运行良好。但是现在我切换到 SpringCrudRepository<T, T>
并收到此错误。我知道问题是关于映射主键约束。但我不知道我到底应该做什么。有人可以帮忙处理吗?
关系类
@Table(name = "RELATIONSHIP")
@Getter
@Setter
@Entity
@ToString
@EqualsAndHashCode
public class Relationship implements Serializable {
@Id
private Long userIdFrom;
@Id
private Long userIdTo;
@Enumerated(EnumType.STRING)
private RelationshipStatus status;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "YYYY-MM-DD HH:mm:ss")
private LocalDate friendsRequestDate;
}
Run Code Online (Sandbox Code Playgroud)
RelationshipRepository.class 仅用于案例
public interface RelationshipRepository extends CrudRepository<Relationship, Long> {
@Query(value = "some query", nativeQuery = true)
Long findAmountOfFriends(@Param("userId") Long userId);
...other methods
}
Run Code Online (Sandbox Code Playgroud)
数据初始化类
@Component
public class DataInit implements ApplicationListener<ContextRefreshedEvent> {
private UserRepository userRepository;
private PostRepository postRepository;
private RelationshipRepository relationshipRepository;
private MessageRepositorys messageRepository;
public DataInit(UserRepository userRepository, PostRepository postRepository, RelationshipRepository relationshipRepository, MessageRepositorys messageRepository) {
this.userRepository = userRepository;
this.postRepository = postRepository;
this.relationshipRepository = relationshipRepository;
this.messageRepository = messageRepository;
}
@Override
@Transactional
public void onApplicationEvent(ContextRefreshedEvent event) {
//here I create users and save them
...
...
...
userRepository.save(someUser);
relationshipRepository.save(relationship);
messageRepository.save(message);
}
}
Run Code Online (Sandbox Code Playgroud)
错误
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataInit' defined in file [C:\Users\tpmylov\Desktop\learning\Projects\socnetw\target\classes\com\socnetw\socnetw\bootstrap\DataInit.class]: Unsatisfied dependency expressed through constructor parameter 2; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'relationshipRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: This class [class com.socnetw.socnetw.model.Relationship] does not define an IdClass
...
...
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'relationshipRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: This class [class com.socnetw.socnetw.model.Relationship] does not define an IdClass
Run Code Online (Sandbox Code Playgroud)
你有一个复合键:
@Id
private Long userIdFrom;
@Id
private Long userIdTo;
Run Code Online (Sandbox Code Playgroud)
为此,您必须创建一个 IdClass:
public class RelationshipId implements Serializable {
private Long userIdFrom;
private Long userIdTo;
// Getter and Setter
}
Run Code Online (Sandbox Code Playgroud)
然后你可以在课堂上使用它
@IdClass(RelationshipId.class)
public class Relationship ....
Run Code Online (Sandbox Code Playgroud)
在存储库上:
public interface RelationshipRepository
extends CrudRepository<Relationship, RelationshipId> {
@Query(value = "some query", nativeQuery = true)
Long findAmountOfFriends(@Param("userId") Long userId);
...other methods
}
Run Code Online (Sandbox Code Playgroud)
在官方 Hibernate 文档中阅读有关复合键的更多信息:
您的实体Relationship
声明假定使用复合主键。因此,您应该通过以下方式更正您的实体:
@Table(name = "RELATIONSHIP")
@Getter
@Setter
@Entity
@ToString
@EqualsAndHashCode
@IdClass(RelationshipPK.class)
public class Relationship implements Serializable {
@Id
private Long userIdFrom;
@Id
private Long userIdTo;
@Enumerated(EnumType.STRING)
private RelationshipStatus status;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "YYYY-MM-DD HH:mm:ss")
private LocalDate friendsRequestDate;
}
Run Code Online (Sandbox Code Playgroud)
进而RelationshipPK
:
public class RelationshipPK implements Serializable {
private Long userIdFrom;
private Long userIdTo;
public RelationshipPK(Long userIdFrom, Long userIdTo) {
this.userIdFrom = userIdFrom;
this.userIdTo = userIdTo;
}
public RelationshipPK() {
}
//Getters and setters are omitted for brevity
@Override
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}
RelationshipPK pk = (RelationshipPK) o;
return Objects.equals( userIdFrom, pk.userIdFrom ) &&
Objects.equals( userIdTo, pk.userIdTo );
}
@Override
public int hashCode() {
return Objects.hash( userIdFrom, userIdTo );
}
}
Run Code Online (Sandbox Code Playgroud)
你CrudRepository
应该有以下观点:
public interface RelationshipRepository extends CrudRepository<Relationship, RelationshipPK>
{
@Query(value = "some query", nativeQuery = true)
Long findAmountOfFriends(@Param("userId") Long userId);
...other methods
}
Run Code Online (Sandbox Code Playgroud)
实际上,hibernate 允许声明一个复合键,但不需要这些东西。这就是所谓的具有关联的复合标识符。但以下CrudRepository方法是必需的:
public interface CrudRepository<T,ID> extends Repository<T,ID>
{
void deleteById(ID id);
boolean existsById(ID id);
Iterable<T> findAllById(Iterable<ID> ids);
Optional<T> findById(ID id);
// ...
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
12008 次 |
最近记录: |