很抱歉长标题..
查询TableColumn
实体时出现以下错误:
无法设置字段值 [org.comp.domain.data.ConstantParameterType@18c81fe5]值 反射:[class org.comp.data.AnalogParameter.analogParameterType] org.comp.data.AnalogParameter.analogParameterType的setter;嵌套 异常是org.hibernate.PropertyAccessException:无法设置 字段值[org.comp.data.ConstantParameterType@18c81fe5]的值 反思:[班级 org.comp.domain.data.AnalogParameter.analogParameterType] setter of org.comp.domain.data.AnalogParameter.analogParameterType
我的模型包含两个区别'每个类的单个表'层次结构,其中Parameter
和ParameterType
为超类。 Parameter
层次结构的每个子类都通过ParameterType
层次结构与@ManyToOne
层次结构的子类进行映射。
这是我的模型的摘录,其中涉及的实体(省略了不相关的字段):
// `Parameter` Single Table Per Class hierarchy
@Entity
@Table(name="parameters")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "category", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorOptions(force=true)
public abstract class Parameter {
}
@Entity
@DiscriminatorValue(value="analog")
public class AnalogParameter extends Parameter {
@ManyToOne
@JoinColumn(name="parameter_type_id")
private AnalogParameterType analogParameterType;
public AnalogParameterType getAnalogParameterType() {
return analogParameterType;
}
public void setAnalogParameterType(AnalogParameterType analogParameterType) {
this.analogParameterType = analogParameterType;
}
}
@Entity
@DiscriminatorValue(value="constant")
public class ConstantParameter extends Parameter {
@ManyToOne
@JoinColumn(name="parameter_type_id")
private ConstantParameterType constantParameterType;
public ConstantParameterType getConstantParameterType() {
return constantParameterType;
}
public void setConstantParameterType(ConstantParameterType constantParameterType) {
this.constantParameterType = constantParameterType;
}
}
// `ParameterType` Single Table Per Class hierarchy
@Entity
@Table(name="parameters_types")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "category", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorOptions(force=true)
public abstract class ParameterType { }
@Entity
@DiscriminatorValue(value="analog")
public class AnalogParameterType extends ParameterType { }
@Entity
@DiscriminatorValue(value="constant")
public class ConstantParameterType extends ParameterType {
}
这是通过@ManyToOne关联与Parameter超类映射的TableColumn:
@Entity
@Table(name="tables_columns")
public class TableColumn {
@ManyToOne
@JoinColumn(name="parameter_id")
private Parameter parameter;
public Parameter getParameter() {
return parameter;
}
}
这是查询TableColumn实体时生成的SQL:
选择tablecolum0_.id为id1_12_0_,tablecolum0_.created_at为 created_2_12_0_,tablecolum0_.is_optional as is_optio3_12_0_, tablecolum0_.parameter_id as paramete6_12_0_,tablecolum0_.position as position4_12_0_,tablecolum0_.updated_at as updated_5_12_0_, parameter1_.id为id2_8_1_,parameter1_.category为category1_8_1_, parameter1_.created_at as created_3_8_1_,parameter1_.device_id as device_14_8_1_,parameter1_.effective_date as effectiv4_8_1_, parameter1_.expiry_date为expiry_d5_8_1_,parameter1_.fqn为 fqn6_8_1_,parameter1_.height_from_the_ground为height_f7_8_1_, parameter1_.label为label8_8_1_,parameter1_.name为name9_8_1_, parameter1_.resolution_label as resolut10_8_1_,parameter1_.updated_at as updated11_8_1_,parameter1_.parameter_type_id as paramet15_8_1_, parameter1_.data_validity_period as data_va12_8_1_, parameter1_.resolution为resolut13_8_1_,device2_.id为id1_1_2_, device2_.created_at as created_2_1_2_,device2_.device_type_id as device_t8_1_2_,device2_.fqn为fqn3_1_2_,device2_.label为 label4_1_2_,device2_.name为name5_1_2_,device2_.notes为 notes6_1_2_,device2_.parent_device_id为parent_d9_1_2_, device2_.plant_id为plant_i10_1_2_,device2_.updated_at为 updated_7_1_2_,constantpa3_.id为id2_9_3_,constantpa3_.created_at as created_3_9_3_,constantpa3_.description as descript4_9_3_, constantpa3_.is_signed as is_signe5_9_3_,constantpa3_.label as label6_9_3_,constantpa3_.name as name7_9_3_,constantpa3_.updated_at as_news_8_9_3_ from tables_columns tablecolum0_ left outer join tablecolum0_.parameter_id = parameter1_.id上的参数parameter1_ 左外连接设备device2_ on parameter1_.device_id = device2_.id left outer join parameters_types constantpa3_ on parameter1_.parameter_type_id = constantpa3_.id其中tablecolum0_.id = 1
我在Spring Boot 1.4.1 / Data Rest项目中使用Hibernate 5.0.11和MySQL
修改
我在一个使用相同数据库的vanilla Maven / Hibernate项目中尝试过。我有同样的错误。如果我直接查询Parameter
个对象,那没关系,但如果我查询TableColumn
,我会收到错误:
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory( "org.hibernate.tutorial.jpa" );
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
// The following works
List<Parameter> ps = entityManager.createQuery("from Parameter", Parameter.class).getResultList();
for (Parameter p: ps) {
System.out.println(p);
}
// But if i replace with following, i get the same error as reported
// in the beginning of this question
List<TableColumn> tcs = entityManager.createQuery("from TableColumn", TableColumn.class).getResultList();
for (TableColumn tc: tcs) {
System.out.println(tc);
}
entityManager.getTransaction().commit();
entityManager.close();
答案 0 :(得分:0)
1)您的category
属于size=7
,但您设置的值为8 characters
,constant
@DiscriminatorColumn(name="category", length=7)//change to more than 7
因为,@DiscriminatorValue(value="constant")//here the length is 8
您可以将以下代码用于Discriminator列:
@DiscriminatorColumn(name = "category", discriminatorType = DiscriminatorType.STRING)//no need of length attribute
2)验证属性private AnalogParameterType analogParameterType;
是否有以下setter和getter方法。
//setter
public void setAnalogParameterType(AnalogParameterType analogParameterType) {
this.analogParameterType = analogParameterType;
}
//getter
public AnalogParameterType getAnalogParameterType() {
return analogParameterType;
}
3)而不是
@ManyToOne
@JoinColumn(name="parameter_type_id")
在 getters 上使用@ManyToOne(cascade=CascadeType.ALL)
例如:
@ManyToOne(cascade = CascadeType.ALL)
public AnalogParameterType getAnalogParameterType() {
return analogParameterType;
}
答案 1 :(得分:0)
所以我通过使用insertable / updatable = false映射两个超类Parameter
和ParameterType
解决了我的问题:
@Entity
@Table(name="parameters")
@DiscriminatorColumn(name = "category", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorOptions(force=true)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Parameter {
@ManyToOne
@JoinColumn(name="parameter_type_id", insertable = false, updatable = false)
private ParameterType parameterType;
}
似乎在超类级别强制执行关联就可以了。我不知道它是纯粹的副作用还是设计需要。我没有找到关于这个问题的任何资源。