Java 在Hibernate中扩展/修改生成的实体
我正在为mysql数据库创建RESTAPI服务。我已经使用IntelliJ的持久化工具生成了类。它做得很好 我正在使用的模式有一些奇怪之处。用户希望端点可由“id”主键列以外的其他属性访问 例如:Java 在Hibernate中扩展/修改生成的实体,java,spring,hibernate,jpa,Java,Spring,Hibernate,Jpa,我正在为mysql数据库创建RESTAPI服务。我已经使用IntelliJ的持久化工具生成了类。它做得很好 我正在使用的模式有一些奇怪之处。用户希望端点可由“id”主键列以外的其他属性访问 例如:/object/”与/object/` 不过,这里有个陷阱。模式可以更改。但是name属性不会在任何地方出现,因此我可以安全地假设它始终在对象上 我了解到,可以使用超类强制这些生成的实体具有自定义属性,而不影响数据库模式。我不想在生成的实体中进行模型更改,并更新数据库表布局,因为它不是我的数据库 我有一
/object/”与
/object/`
不过,这里有个陷阱。模式可以更改。但是name属性不会在任何地方出现,因此我可以安全地假设它始终在对象上
我了解到,可以使用超类强制这些生成的实体具有自定义属性,而不影响数据库模式。我不想在生成的实体中进行模型更改,并更新数据库表布局,因为它不是我的数据库
我有一门课叫动物
@Entity
@Table(name = "animals", schema = "xyz123", catalog = "")
public class AnimalEntity extends AnimalSuperclass {
private Integer id;
private String name;
private String description;
@Id
@Column(name = "id", nullable = false)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Basic
@Column(name = "name", nullable = true, length = 80)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Basic
@Column(name = "description", nullable = true, length = 255)
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RoleEntity that = (RoleEntity) o;
return Objects.equals(id, that.id) &&
Objects.equals(name, that.name) &&
Objects.equals(description, that.description);
}
@Override
public int hashCode() {
return Objects.hash(id, name, description);
}
}
我必须手动添加扩展AnimalSuperclass。现在还可以。最后,我将尝试在运行时使用.xmls生成这些
然后我有了这个超类
@MappedSuperclass
public class AnimalSuperclass implements Serializable {
private String testMessage;
private String name;
private Integer id;
@Transient
public String getTestMessage() {
return this.testMessage;
}
public void setTestMessage(String id) {
this.testMessage = testMessage;
}
}
我要做的是从超类中强制将@Id
注释放在name属性上。像这样的。。
@映射超类
公共类AnimalSuperclass实现可序列化{
私有字符串测试消息;
私有字符串名称;
私有整数id
@Transient
public String getTestMessage() {
return this.testMessage;
}
public void setTestMessage(String id) {
this.testMessage = testMessage;
}
@Basic
@Id
@Column(name = "name", nullable = false, length = 15)
private String getName() {
return name;
}
private void setName(String name) {
this.name = name;
}
@NaturalId
@Column(name = "id", nullable = false)
private Integer getId() {
return id;
}
private void setId(Integer id) {
this.id = id;
}
}
如何执行该操作?当前,当我到达端点时,这会引发一个错误:{“原因”:null,“消息”:“Id必须可分配给Serializable!:null”}
Java不是我的第一语言,所以我无论如何都不是专家。但从我所读到的内容来看,不可能从超类重写子类属性。有没有更好的方法来实现这一点,也许可以使用
RepositoryRestConfiguration
?我正在使用paging和sortingrepository
来为这些实体服务。我无法使用ext结束实体并将我的超类用作子类,因为它会在架构中创建dType
属性,并且我无法更改表布局。请求和实体之间没有硬链接。在存储库中,您可以编写方法来查询从请求中获取的数据
例如,如果他们要求一个名字,你可以这样做
Page<AnimalEntity> findByName(String name, Pageable pageable);
Page findByName(字符串名称,可分页);
Spring将处理其余部分,然后您可以在控制器中调用它
@Service
public class AnimalService {
@Autowired
private AnimalEntityRepository animalRepo;
public Page<AnimalEntity> findAnimal(String name) {
Page<AnimalEntity> animals = animalRepo.findByName(name, new PageRequest(1,20));
return animals;
}
}
@服务
公共级动物服务{
@自动连线
私人动物报告;
公共页findAnimal(字符串名称){
页面动物=animalRepo.findByName(名称,新页面请求(1,20));
归还动物;
}
}
需要指出的一点是,根据您在将实体发送回客户机时配置Hibernate的方式以及实体的序列化方式,您可能会遇到无法延迟初始化的错误。如果是这种情况,您的实体将必须转换为POJO(纯旧java对象)谢谢!这正是我想要的。存储库方法findbyName的最终形式如何?我尝试将它们添加到中,但/animal/endpoint仍然查找整数id。我应该提到我使用的是HATEOAS,所以我只有模型和存储库。除此之外,没有自定义控制器我们有c已创建。我现在了解其工作流程。但当我尝试使用浏览器转到
/animal/cheetah
时,spring仍然认为我在使用id,并给出了以下错误:为hello.models.AnimalEntity提供了错误类型的id。预期:class java.lang.Integer,获得class java.lang.String
。如果我设置了breakpoint在该findAnimal函数中,它永远不会到达该代码。我肯定cheetah的名称已填充。您可以更新发送数据的客户端代码段和处理请求的服务器代码的OP吗?Nvm,@蝗虫2K更新为@PathVariable
,而不是@RequestParam
,它可以工作。我如何保留是否使用以前的格式进行分页?