存储库继承

时间:2013-05-21 20:14:34

标签: java jpa

我想创建一个执行基本CRUD操作的存储库。

由于我有不同类型的照片(CompanyPhoto,CarPhoto,..),我更愿意将JPA存储库设为通用存储库,而且也是EJB服务。

这是我的课程:

    @Entity
    @Inheritance
    @DiscriminatorColumn(name = "DESCRIMINATOR")
    @Table(name = "PHOTOS")
    public abstract class Photo {
        public Photo() {
        }

        public Photo(String fileName) {
            this.fileName = fileName;
    //      this.file = file;
        }

        @Id
        @GeneratedValue(strategy = GenerationType.TABLE, generator = "PHOTOS_SEQ")
        @TableGenerator(name = "PHOTOS_SEQ", table = "SEQUENCE", pkColumnName = "SEQ_NAME", pkColumnValue = "PHOTOS_SEQ", valueColumnName = "SEQ_COUNT", allocationSize = 50)
        @Column(nullable = false)
        private long id;

        @Column(length = 255)
        @Size(min = 0, max = 255, message = "{Photo.description.size}")
        protected String description;

        @Column(nullable = false, length = 255)
        @NotNull(message = "{Photo.fileName.notNull}")
        @Size(min = 1, max = 255, message = "{Photo.fileName.size}")
        protected String fileName;

        // ...

@Entity
@DiscriminatorValue("C")
public class CarPhoto extends Photo {

    public CarPhoto() {

    }

    public CarPhoto(String fileName) {
        super.fileName = fileName;
    }

    @ManyToOne(cascade = { CascadeType.DETACH })
    @JoinColumn(name = "CARID", nullable = false)
    @NotNull
    private Car car;
        // ...

@Entity
@DiscriminatorValue("P")
public class PersonPhoto extends Photo {

    public PersonPhoto() {

    }

    public PersonPhoto(String fileName) {
        super.fileName = fileName;
    }

    @ManyToOne(cascade = { CascadeType.DETACH })
    @JoinColumn(name = "PERSONID", nullable = false)
    @NotNull
    private Person person;
        // ...

@Stateless
@LocalBean
public class PhotoRepository<E> {

        // In this class I would like to do create, remove, update and some basic find       //operations..


    @PersistenceContext
    private EntityManager em;

    public PhotoRepository() {
    }

    PhotoRepository(EntityManager em) {
        this.em = em;
    }

    @Override
    public E create(E photo) {
        em.persist(photo);
        return photo;
    }

    @Override
    public E modify(E photo)
    {
        Class<E> photoClass;
                // QUESTION: How am I going to call the getId() method from the object of type E  class?
        em.find(photoClass, photo.getId()); // This will not work.. =(
        E mergedPhoto = em.merge(photo);
        return mergedPhoto;
    }
        // ...

我希望你明白我想要表演的。所有类都继承自同一个基类的类的通用存储库。你能给我一些最佳实践的例子吗?  =)

祝你好运

2 个答案:

答案 0 :(得分:1)

您可以使用

从实体获取ID
entityManagerFactory.getPersistenceUnitUtil().getIdentifier(object);

虽然你不需要在merge()之前调用find(),只需调用merge(),它会在需要时执行查找。

答案 1 :(得分:1)

更改泛型定义,使E必须是从Photo扩展的任何类型。然后,您将能够在类型E

的变量上访问Photo类的方法
@Stateless
@LocalBean
public class PhotoRepository<E extends Photo> {

您可以使用以下方法检索实际的类。

public Class getEntityClass() {
  ParameterizedType parameterizedType =
    (ParameterizedType) getClass().getGenericSuperClass();
 return (Class) parameterizedtype.getActualTypeArguments()[0];
}

如果你使用spring,你还应该看看spring-data-jpa - 它提供了这样的通用存储库实现。