如何使通用类对多个实体使用JPARepository

时间:2019-03-11 15:20:05

标签: java spring-boot jpa spring-data-jpa

场景: 一个应用程序具有多个实体。每个实体表示一个数据库表。所有数据库表都具有主键列,但列名不同。

实体示例:

@Entity
@Table(name = "ABC",schema = "XYZ" )
public class SaveData extends EntityClass {

    @Id
    @Column(name = "ABC_ID", nullable = false, insertable = true, updatable = true, precision = 0)
    private int id;

    @Column(name = "ABC1_ID", nullable = false, insertable = true, updatable = true, precision = 0)
    private int abc1_id;

    @Column(name = "DATA", nullable = true, insertable = true, updatable = true, precision = 0)
    private String data;

   //Getter - Setter methods of the above member variables.

}

EntityClass类似于泛型类。所有实体类都将扩展此抽象类。

@MappedSuperclass
public abstract class EntityClass {

    @Id
    private int id;
}

该应用程序的Dao界面为:

@Repository
public interface DaoRepos extends JpaRepository<EntityClass,Long> {

}

服务等级示例:

@Component
public class ServiceMethodsImpl implements ServiceMethods {

    @Autowired
    private DaoRepos daoRepos ;

    @Override
    public void saveDatainDB(SaveData saveData ) {
        daoRepos.save(saveData);
    }

}

问题: 如果我像下面这样声明dao接口:

@Repository
public interface ReviewRepos extends JpaRepository<SaveData,Long> {

}

在JPARepository中将参数发送为SaveData,然后在服务类中使用我的saveDatainDB方法即可。

现在仅用于保存实体的数据。同样,存在其他实体,并且需要应用相同的保存功能。因此,我想到了创建一个将代表所有实体的通用类(在本示例中为EntityClass)。该类将作为参数发送到JPARepository,以便在运行时,我们可以用子类(例如EntityClass)覆盖SaveData

但是Spring不允许在没有EntityClass列的情况下创建类@Id。因此,我必须声明一个ID列。同样在我的数据库中,每个表都有一个主列,但是所有表中该列的名称都不相同。 例如, 表XYZ将具有主列xyz_id 表ABC将具有主列abc_id

因此,我必须在子类实体SaveData中定义一个带有@Column批注的ID列。

现在,当我尝试保存时,除了id类中存在的id列之外,还会创建一个单独的SaveData列。额外的id会产生错误,如unrecognized column

在处理此问题方面的任何帮助将不胜感激。 另外,请验证我的方法是否正确。

1 个答案:

答案 0 :(得分:1)

对于旧系统,可以使用@AttributeOverride注释覆盖id列名称。

@Entity
@AttributeOverride(name="id", column=@Column(name="ABC_ID"))
@Table(name = "ABC",schema = "XYZ" )
public class SaveData extends EntityClass {

    @Column(name = "ABC1_ID", nullable = false, insertable = true, updatable = true, precision = 0)
    private int abc1_id;

    @Column(name = "DATA", nullable = true, insertable = true, updatable = true, precision = 0)
    private String data;    
}