Eclipselink Discriminator列返回NULL

时间:2016-11-07 12:37:54

标签: java eclipselink discriminator

这个问题围绕着JPA和Discriminators。

动机:我正在实现一个包含各种字段的系统,这些字段需要一些域值。例如,字段类型(性别类型:男性和女性; ID类型:驾驶执照;大道类型等等)。

由于我的系统是元数据驱动的,因此我不会将这些属性创建为ENUM。我需要它们在一个容易取出的地方。

为了做到这一点,我创建了一个标记为ALNDOMAIN(Alpha Numeric Domains)的父抽象类。并且所有继承的类都将成为我的对象的一部分(例如,IDType扩展了ALNDomain)。

问题:我的系统将有大约200个ALNDomains子类。我不想为每个子类创建一个存储库。我更喜欢在ALNDomain类中有一个存储库并获取Discriminator Value。每当我获取我的域时,鉴别器列将变为NULL:

@Entity
@DiscriminatorColumn(name="ALNNAME", discriminatorType = DiscriminatorType.STRING)
public abstract class ALNDomain {

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Long id;
	
	@Column(name="ALNNAME", insertable = false, updatable = false, nullable = false)
	private String alnname;
	private String value;
	private String description;
	
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getValue() {
		return value;
	}
	public void setValue(String value) {
		this.value = value;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	public String getAlnname() {
		return alnname;
	}
	public void setAlnname(String alnname) {
		this.alnname = alnname;
	}
}

这是子类:

package com.ang.entity.core;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

import com.ang.entity.base.domains.ALNDomain;

@Entity
@DiscriminatorValue("IDTYPE")
public class IDType extends ALNDomain {

}

这是我的存储库:

@RepositoryRestResource(collectionResourceRel = "alndomain", path = "alndomain")
@CrossOrigin(maxAge = 3600)
public interface ALNDomainRepository extends PagingAndSortingRepository<ALNDomain, Long>{
	List<ALNDomain> findByAlnname(@Param("alnname") String alnname);
}

当我访问我的存储库时,discriminator列为null。这就是结果:

{
  "_embedded" : {
    "iDTypes" : [ {
      **"alnname" : null,**
      "value" : "RG",
      "description" : "Registro Nacional",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/iDType/1"
        },
        "iDType" : {
          "href" : "http://localhost:8080/iDType/1"
        }
      }
    } ]
  },

ALNNAME不应为null。我需要它来避免创建200个存储库来访问每种类型的ALNDOMAIN的所有可能值列表。

感谢您的关注。

2 个答案:

答案 0 :(得分:0)

您的实体有两个映射到“ALNNAME”列 -

  1. 使用@DiscriminatorColumn和指定的类类型 @DiscriminatorValue注释。

  2. alnname属性通过@Column设置只读标记。

  3. 这两个映射完全相互独立,在JPA中没有链接。因此,如果从数据库加载实体时将设置alnname,那么在此之前它将不会由JPA设置。

    虽然JPA在查询中支持TYPE函数,但Java实例能够获取类名,但这个属性几乎完全是多余的。如果必须将此属性保存在实体中,则最好在创建子类的新实例时设置它,或者改为覆盖子类上的get方法以返回所需的字符串。无法更改实例上的值 - java不允许您将对象从一个类转换为另一个类,因此在JPA中无法创建全新实例。

答案 1 :(得分:0)

我发现的方法是基于Class类型以dinamically方式实例化一个Repository,因为我在Server中。

基本上我替换了我的方法: 列表findByAlnname(@Param(“alnname”)String domainClassName)

执行以下操作:

        Class domainClass;
        try {
            domainClass = ClassLoader.getSystemClassLoader().loadClass(domainClassName);
            if (domainClass!=null && ALNDomain.class.isAssignableFrom(domainClass)) {

                SimpleJpaRepository<ALNDomain, Long> jpaRep = new SimpleJpaRepository<ALNDomain, Long>(domainClass,em);

                return jpaRep.findAll();
            }   
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }