2个POJO类扩展了一个Base类,其中每个类映射到唯一表。为什么hibernate查询会在字段列表错误中创建未知列'''?

时间:2018-06-15 09:30:51

标签: java mysql hibernate inheritance hibernate-mapping

我有2个类扩展基类。

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个类都扩展了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个表都映射到MySQL数据库中的唯一表。

以下是每个表的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类中,SQL查询是这样的。(SQL查询是针对派生类的)

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   '字段列表'中的列'qid'

问题 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");在基类上,看起来它正在与所有子类建立联合,而子类没有添加时间列。我只是在猜测。

4 个答案:

答案 0 :(得分:0)

然后错误是由于在hibernate映射的表中没有列,即通常defoult的字段采用属性的名称。 我想问你的第一个问题是表格已经存在于DB上了?你为什么要在做任何你需要知道的事情之前知道你正在映射谁,而在正常的Hibernate中使用这些类让他们自己被映射到他。 因此,当我可以找到关于hibernate来解决你要兑换的问题的时候,你应该将一个类映射到你在DB上的那个类,然后将“支持类”映射到你的实际模型。 键入从服务器获取数据时使用的解决方案,但数据不反映当前模型。

我希望我已根据您的问题作出回应并提供了帮助。

PS:尝试检查你的db hibernate是否还没有创建其他关系tabbell。

答案 1 :(得分:0)

我尝试在hibernate版本4.x.x中发布一些代码,为什么不编写查询而不尝试使用Creteria和Restrictions? creteria为您提供了一个列表,您可以决定是否要返回已经订购的列表,例如在我的平庸代码中,我有一个通用的DAO,通过creteria实现查询。

&#13;
&#13;
//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());
        }
    }
&#13;
&#13;
&#13;

答案 2 :(得分:0)

将继承策略更改为JOINED。 @Inheritance(strategy = InheritanceType.JOINED)。

您可能需要在问题表中添加问题类型列,这是您需要作为问题类注释的问题类型的鉴别列。

 @Inheritance(strategy = InheritanceType.JOINED)
 @DiscriminatorColumn(name = "QUESTION_TYPE")
 public class Questions{
 .
 .
 }

并且,在子类中,您可以使用@DiscriminatorValue注释来提供鉴别器值。

@DiscriminatorValue("MCQ")
public class MCQ extends Questions implements Serializable{
.
}

@DiscriminatorValue("TwoMarkQ")
public class TwoMarkQ extends Questions implements Serializable{
.
}

并从子类中删除@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)。

答案 3 :(得分:0)

好的,这就是我解决此问题的方式。

根本原因是扩展了基类Question。 我创建了一个名为Ques的新类,该类由Question.java,MCQ.java和TwoMarkQ.java实现。

根据Hibernate documentation

我们提供3个选项。 b'InheritanceType.TABLE_PER_CLASSInheritanceType.SINGLE_TABLE

InheritanceType.JOINED绝对不是我想要的。所以这是一个排除的选项。

JOINED:

单表继承策略将所有子类映射到一个数据库表,因此这也导致子类的联合扩展了基类。

我仍然关注

SINGLE_TABLE: 

关于Question.java,MCQ.java和TwoMark.java

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Polymorphism(type=PolymorphismType.EXPLICIT) 

“使用多态查询时,还需要UNION来获取基类表以及所有子类表。” -所以这也是一个排除的选项。

此外,我删除了表之间的外键引用。