在Hibernate中扩展/修改生成的实体

时间:2018-07-05 16:27:16

标签: java spring hibernate jpa

我正在为mysql数据库创建REST api服务。我已经使用IntelliJ的持久性工具生成了类。它做得很好。

我正在使用的架构有一些古怪之处。用户希望端点可以通过“ id”主键列以外的其他属性访问。

例如:/object/<name property>' versus / 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属性上。像这样         @MappedSuperclass         公共类AnimalSuperclass实现了Serializable {             私有字符串testMessage;             私有字符串名称;             私人整数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;
        }
    }

我该如何做?目前,当我点击以下端点时,这会引发错误:{"cause":null,"message":"Id must be assignable to Serializable!: null"}

Java不是我的母语,因此无论如何我都不是专家。但是据我所读,不可能覆盖超类的子类属性。是否有更好的方法可以解决此问题,例如使用RepositoryRestConfiguration?我正在使用PagingAndSortingRepository为这些实体提供服务。我无法扩展实体并将超类用作子级,因为它会在架构中创建dType属性,并且无法更改表布局。

1 个答案:

答案 0 :(得分:0)

请求与您的实体之间没有硬链接。在您的存储库中,您可以编写一些方法来查询从请求中获取的数据。

例如,如果他们要一个名字,您可以做类似的事情

Page<AnimalEntity> findByName(String name, Pageable pageable);

在您的存储库中。 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;
  }
}

要提及的一件事是,根据将实体发送回客户端时该配置的方式以及该实体被序列化的方式,您可能会遇到延迟初始化失败的错误。如果是这种情况,则必须将您的实体转换为POJO(普通的Java对象)并将其发送回去。