2 POJO classes 扩展了一个 Base class,其中每个 class 映射到唯一的 table。为什么休眠查询在“字段列表错误”中创建未知列“”?
2 POJO classes extends a Base class where each class maps to unique table. Why hibernate query creates Unknown column '' in 'field list error?
我有 2 个 classes 扩展一个基础 class。
Questions.java
@Entity
@Table(name="question")
@Access(value = AccessType.FIELD)
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Questions{
private static final long serialVersionUID = 1L;
private String qid;
@Column(name="addedtime")
private String addedtime;
@Column(name="qlang")
private String qlang;
@Id
@Column(name="qid")
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Access(value = AccessType.PROPERTY)
public String getQid() {
return qid;
}
public void setQid(String qid) {
this.qid = qid;
}
@Access(value = AccessType.PROPERTY)
public String getAddedtime() {
return addedtime;
}
public void setAddedtime(String addedtime) {
this.addedtime = addedtime;
}
@Access(value = AccessType.PROPERTY)
public String getQlang() {
return qlang;
}
public void setQlang(String qlang) {
this.qlang = qlang;
}
}
MCQ.java、TwoMarkQ.java - 所有 2 classes 扩展 Question.java.
MCQ.java
@Entity
@Table(name="MCQ")
@Access(value = AccessType.FIELD)
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class MCQ extends Questions implements Serializable{
@Column(name="option_1")
@Access(value = AccessType.FIELD)
private String option_1;
@Access(value = AccessType.PROPERTY)
public String getOption_1() {
return option_1;
}
public void setOption_1(String option_1) {
this.option_1 = option_1;
}
@Column(name="option_2")
@Access(value = AccessType.FIELD)
private String option_2;
@Access(value = AccessType.PROPERTY)
public String getOption_2() {
return option_2;
}
public void setOption_2(String option_2) {
this.option_2 = option_2;
}
}
TwoMarkQ.java
@Entity
@Table(name="TwoMarkQ")
@Access(value = AccessType.FIELD)
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class TwoMarkQ extends Questions implements Serializable{
@Column(name="option_1")
@Access(value = AccessType.FIELD)
private String option_1;
@Access(value = AccessType.PROPERTY)
public String getOption_1() {
return option_1;
}
public void setOption_1(String option_1) {
this.option_1 = option_1;
}
@Column(name="option_2")
@Access(value = AccessType.FIELD)
private String option_2;
@Access(value = AccessType.PROPERTY)
public String getOption_2() {
return option_2;
}
public void setOption_2(String option_2) {
this.option_2 = option_2;
}
}
所有这 3 个 table 都映射到 MySQL 数据库中唯一的 table。
以下是每个 table
的 show create table 的结果
create table `question` (
`qid` varchar(48) COLLATE utf8mb4_unicode_ci NOT NULL,
`addedtime` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
`qtype` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`qlang` varchar(48) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`qid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
create table `MCQ`(
`qid` varchar(48) COLLATE utf8mb4_unicode_ci NOT NULL,
`option_1` bigint(20) DEGAULT `0`,
`option_2` bigint(20) DEGAULT `0`,
PRIMARY KEY (`qid`),
CONSTRAINT `mcq_ibfk1` FOREIGN KEY (`qid`) REFERENCES `question` (`qid`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
create table `TwoMarkQ`(
`qid` varchar(48) COLLATE utf8mb4_unicode_ci NOT NULL,
`option_1` bigint(20) DEGAULT `0`,
`option_2` bigint(20) DEGAULT `0`,
PRIMARY KEY (`qid`),
CONSTRAINT `two_markq_ibfk1` FOREIGN KEY (`qid`) REFERENCES `question` (`qid`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
在其中一个 DAO class 中,SQL 查询是这样的。(SQL 查询是针对派生的 class)
Query query = session.createQuery("select q.qid, q.qtype from Questions q where q.qlang=:lang ORDER BY q.addedtime ASC");
query.setParameter("lang", lang);
query.setFirstResult(startingRow).setMaxResults(10);
result = (List<Questions>) query.list();
上面一行出现错误result = (List<Questions>) query.list();
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown
column 'qid' in 'field list'
问题
1) 为什么我得到 com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'addedtime' in 'field list'
以及如何解决它?
请帮忙。坚持了3天。
PS:我使用的是 Hibernate 4.3 版。5.Final
PS:这是生成的查询
select questions0_.qid as col_0_0_, questions0_.qtype as col_1_0_ from ( select qid, addedtime, qlang, qtype, null as option_1, null as option_2 as class_ from MCQ union select qid, addedtime, qlang, qtype, null as option_!, null as option_2 as class_ from TwoMarkQ) questions0_ where questions0_.qlang=? order by questions0_.addedtime ASC limit ?
因为 Query query = session.createQuery("select q.qid, q.qtype from Questions q where q.qlang=:lang ORDER BY q.addedtime ASC");
在基础 class 上,看起来它正在与所有子 classes 合并,而子 classes 没有添加时间列。我只是猜测。
然后错误是由于在hibernate映射的table中没有列,即通常默认的字段采用属性的名称。
我想问你的第一个问题是 table 已经存在于数据库中??你为什么在做任何事情之前休眠你需要知道你在映射谁,在正常的休眠中使用 classes 让自己被映射到他。
因此,当我找到有关休眠的信息来解决您要解决的问题时,您应该将单个 class 映射到数据库中的那个,然后再将 "class of support" 映射到您的实际模型。
键入从服务器获取数据时使用的解决方案,并且该数据不反映您当前的模型。
希望我的回答与您的问题一致,对您有所帮助。
PS: 尝试检查你的数据库休眠是否没有创建其他关系标签。
我尝试 post 我的一些休眠版本的代码 4.x.x,为什么不写查询而不是尝试使用 Creteria 和限制? creteria 给你一个列表,你可以决定是否要 return 它已经订购,例如在我的一个人的搜索的平庸代码中我有一个通用的 DAO,它通过 creteria 实现查询。
//DAO Generic
public List<T> findByCriteria(Criterion... criterion) throws DAOException {
try {
Criteria crit = getSession().createCriteria(getPersistentClass());
for (Criterion c : criterion) {
crit.add(c);
}
return crit.list();
} catch (HibernateException ex) {
logger.error(ex.getLocalizedMessage());
throw new DAOException(ex);
}
}
//DAO person
public List<Persona> findByCognome(String cognome) throws DAOException {
try {
Criteria criteria = getSession().createCriteria(Persona.class);
criteria.add(Restrictions.eq("cognome", cognome).ignoreCase());
criteria.addOrder(Order.asc("eta"));
return criteria.list();
} catch (DAOException ex) {
throw new DAOException(ex.getLocalizedMessage());
}
}
将继承策略更改为 JOINED。
@Inheritance(策略=InheritanceType.JOINED)。
您可能需要为问题 table 中的问题类型添加一列,这是您需要作为注释放在问题 class 上的问题类型的鉴别器列。
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "QUESTION_TYPE")
public class Questions{
.
.
}
并且,在 child classes 中,您可以使用 @DiscriminatorValue 注释提供鉴别器值。
@DiscriminatorValue("MCQ")
public class MCQ extends Questions implements Serializable{
.
}
和
@DiscriminatorValue("TwoMarkQ")
public class TwoMarkQ extends Questions implements Serializable{
.
}
并从 child classes.
中删除 @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
好的,这就是我解决这个问题的方法。
根本原因是扩展基础 class 问题。
我创建了一个名为 Ques 的新 class,它由 Question.java、MCQ.java 和 TwoMarkQ.java
实现
我们提供了 3 个选项。
InheritanceType.TABLE_PER_CLASS
或 InheritanceType.SINGLE_TABLE
或 InheritanceType.JOINED
JOINED:
绝对不是我想要的。所以这是一个被排除的选项。
SINGLE_TABLE:
单一 table 继承策略将所有子 class 映射到仅一个数据库 table.So 这也导致子 class 扩展基础 [=46] 的并集=].
我还有关注
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Polymorphism(type=PolymorphismType.EXPLICIT)
在 Question.java、MCQ.java 和 TwoMark.java
TABLE_PER_CLASS
"When using polymorphic queries, a UNION is required to fetch the base class table along with all subclass tables as well." - 所以这也是一个被排除的选项。
此外,我删除了 table 之间的外键引用。
我有 2 个 classes 扩展一个基础 class。
Questions.java
@Entity
@Table(name="question")
@Access(value = AccessType.FIELD)
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Questions{
private static final long serialVersionUID = 1L;
private String qid;
@Column(name="addedtime")
private String addedtime;
@Column(name="qlang")
private String qlang;
@Id
@Column(name="qid")
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Access(value = AccessType.PROPERTY)
public String getQid() {
return qid;
}
public void setQid(String qid) {
this.qid = qid;
}
@Access(value = AccessType.PROPERTY)
public String getAddedtime() {
return addedtime;
}
public void setAddedtime(String addedtime) {
this.addedtime = addedtime;
}
@Access(value = AccessType.PROPERTY)
public String getQlang() {
return qlang;
}
public void setQlang(String qlang) {
this.qlang = qlang;
}
}
MCQ.java、TwoMarkQ.java - 所有 2 classes 扩展 Question.java.
MCQ.java
@Entity
@Table(name="MCQ")
@Access(value = AccessType.FIELD)
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class MCQ extends Questions implements Serializable{
@Column(name="option_1")
@Access(value = AccessType.FIELD)
private String option_1;
@Access(value = AccessType.PROPERTY)
public String getOption_1() {
return option_1;
}
public void setOption_1(String option_1) {
this.option_1 = option_1;
}
@Column(name="option_2")
@Access(value = AccessType.FIELD)
private String option_2;
@Access(value = AccessType.PROPERTY)
public String getOption_2() {
return option_2;
}
public void setOption_2(String option_2) {
this.option_2 = option_2;
}
}
TwoMarkQ.java
@Entity
@Table(name="TwoMarkQ")
@Access(value = AccessType.FIELD)
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class TwoMarkQ extends Questions implements Serializable{
@Column(name="option_1")
@Access(value = AccessType.FIELD)
private String option_1;
@Access(value = AccessType.PROPERTY)
public String getOption_1() {
return option_1;
}
public void setOption_1(String option_1) {
this.option_1 = option_1;
}
@Column(name="option_2")
@Access(value = AccessType.FIELD)
private String option_2;
@Access(value = AccessType.PROPERTY)
public String getOption_2() {
return option_2;
}
public void setOption_2(String option_2) {
this.option_2 = option_2;
}
}
所有这 3 个 table 都映射到 MySQL 数据库中唯一的 table。
以下是每个 table
的 show create table 的结果create table `question` (
`qid` varchar(48) COLLATE utf8mb4_unicode_ci NOT NULL,
`addedtime` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
`qtype` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`qlang` varchar(48) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`qid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
create table `MCQ`(
`qid` varchar(48) COLLATE utf8mb4_unicode_ci NOT NULL,
`option_1` bigint(20) DEGAULT `0`,
`option_2` bigint(20) DEGAULT `0`,
PRIMARY KEY (`qid`),
CONSTRAINT `mcq_ibfk1` FOREIGN KEY (`qid`) REFERENCES `question` (`qid`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
create table `TwoMarkQ`(
`qid` varchar(48) COLLATE utf8mb4_unicode_ci NOT NULL,
`option_1` bigint(20) DEGAULT `0`,
`option_2` bigint(20) DEGAULT `0`,
PRIMARY KEY (`qid`),
CONSTRAINT `two_markq_ibfk1` FOREIGN KEY (`qid`) REFERENCES `question` (`qid`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
在其中一个 DAO class 中,SQL 查询是这样的。(SQL 查询是针对派生的 class)
Query query = session.createQuery("select q.qid, q.qtype from Questions q where q.qlang=:lang ORDER BY q.addedtime ASC");
query.setParameter("lang", lang);
query.setFirstResult(startingRow).setMaxResults(10);
result = (List<Questions>) query.list();
上面一行出现错误result = (List<Questions>) query.list();
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'qid' in 'field list'
问题
1) 为什么我得到 com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'addedtime' in 'field list'
以及如何解决它?
请帮忙。坚持了3天。
PS:我使用的是 Hibernate 4.3 版。5.Final
PS:这是生成的查询
select questions0_.qid as col_0_0_, questions0_.qtype as col_1_0_ from ( select qid, addedtime, qlang, qtype, null as option_1, null as option_2 as class_ from MCQ union select qid, addedtime, qlang, qtype, null as option_!, null as option_2 as class_ from TwoMarkQ) questions0_ where questions0_.qlang=? order by questions0_.addedtime ASC limit ?
因为 Query query = session.createQuery("select q.qid, q.qtype from Questions q where q.qlang=:lang ORDER BY q.addedtime ASC");
在基础 class 上,看起来它正在与所有子 classes 合并,而子 classes 没有添加时间列。我只是猜测。
然后错误是由于在hibernate映射的table中没有列,即通常默认的字段采用属性的名称。 我想问你的第一个问题是 table 已经存在于数据库中??你为什么在做任何事情之前休眠你需要知道你在映射谁,在正常的休眠中使用 classes 让自己被映射到他。 因此,当我找到有关休眠的信息来解决您要解决的问题时,您应该将单个 class 映射到数据库中的那个,然后再将 "class of support" 映射到您的实际模型。 键入从服务器获取数据时使用的解决方案,并且该数据不反映您当前的模型。
希望我的回答与您的问题一致,对您有所帮助。
PS: 尝试检查你的数据库休眠是否没有创建其他关系标签。
我尝试 post 我的一些休眠版本的代码 4.x.x,为什么不写查询而不是尝试使用 Creteria 和限制? creteria 给你一个列表,你可以决定是否要 return 它已经订购,例如在我的一个人的搜索的平庸代码中我有一个通用的 DAO,它通过 creteria 实现查询。
//DAO Generic
public List<T> findByCriteria(Criterion... criterion) throws DAOException {
try {
Criteria crit = getSession().createCriteria(getPersistentClass());
for (Criterion c : criterion) {
crit.add(c);
}
return crit.list();
} catch (HibernateException ex) {
logger.error(ex.getLocalizedMessage());
throw new DAOException(ex);
}
}
//DAO person
public List<Persona> findByCognome(String cognome) throws DAOException {
try {
Criteria criteria = getSession().createCriteria(Persona.class);
criteria.add(Restrictions.eq("cognome", cognome).ignoreCase());
criteria.addOrder(Order.asc("eta"));
return criteria.list();
} catch (DAOException ex) {
throw new DAOException(ex.getLocalizedMessage());
}
}
将继承策略更改为 JOINED。 @Inheritance(策略=InheritanceType.JOINED)。
您可能需要为问题 table 中的问题类型添加一列,这是您需要作为注释放在问题 class 上的问题类型的鉴别器列。
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "QUESTION_TYPE")
public class Questions{
.
.
}
并且,在 child classes 中,您可以使用 @DiscriminatorValue 注释提供鉴别器值。
@DiscriminatorValue("MCQ")
public class MCQ extends Questions implements Serializable{
.
}
和
@DiscriminatorValue("TwoMarkQ")
public class TwoMarkQ extends Questions implements Serializable{
.
}
并从 child classes.
中删除 @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)好的,这就是我解决这个问题的方法。
根本原因是扩展基础 class 问题。 我创建了一个名为 Ques 的新 class,它由 Question.java、MCQ.java 和 TwoMarkQ.java
实现我们提供了 3 个选项。
InheritanceType.TABLE_PER_CLASS
或 InheritanceType.SINGLE_TABLE
或 InheritanceType.JOINED
JOINED:
绝对不是我想要的。所以这是一个被排除的选项。
SINGLE_TABLE:
单一 table 继承策略将所有子 class 映射到仅一个数据库 table.So 这也导致子 class 扩展基础 [=46] 的并集=].
我还有关注
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Polymorphism(type=PolymorphismType.EXPLICIT)
在 Question.java、MCQ.java 和 TwoMark.java
TABLE_PER_CLASS
"When using polymorphic queries, a UNION is required to fetch the base class table along with all subclass tables as well." - 所以这也是一个被排除的选项。
此外,我删除了 table 之间的外键引用。