2POJO类扩展了一个基类,其中每个类Map到唯一的表为什么hibernate查询在字段列表错误中创建未知列“”?

wf82jlnq  于 2021-06-20  发布在  Mysql
关注(0)|答案(4)|浏览(271)

我有两个扩展基类的类。
问题.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—这两个类都扩展了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;
    }

}

这三个表都Map到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:字段列表中的未知列“qid”
问题1)为什么我会 com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'addedtime' in 'field list' 如何修复?
请帮忙。在这上面敲了三天。
ps:我使用的是Hibernate4.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"); 在基类上,看起来它正在与所有子类进行并集,子类没有addedtime列。我只是在猜测。

toe95027

toe950271#

然后,这个错误是由于在hibernateMap的表中没有列,即通常defoult采用属性名称的字段。我想问你的第一个问题是db上的表已经存在了??为什么在做任何需要知道Map对象的事情之前先禁用,在正常的hibernate中使用类让它们自己Map到他。因此,当我可以找到关于hibernate的信息来解决您正在赎回的问题时,您应该将一个类与db上的类进行Map,然后再将“支持类”Map到您的实际模型。键入从服务器获取数据时使用的解决方案,该数据不反映当前模型。
我希望我的回答与你的问题一致,并对你有所帮助。
ps:尝试检查db hibernate是否没有创建其他关系选项卡。

eqoofvh9

eqoofvh92#

我试着在hibernate版本4.x.x中发布一些代码,为什么不尝试使用creteria和限制而编写查询呢?creteria提供了一个列表,您可以决定是否要返回已排序的列表,例如在我的个人搜索的普通代码中,我有一个通过creteria实现查询的通用dao。

//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());
        }
    }
s4chpxco

s4chpxco3#

将继承策略更改为joined@继承(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\u per\u class)。

vlurs2pr

vlurs2pr4#

好的,我就是这样解决这个问题的。
根本原因是扩展了基类问题。我创建了一个名为ques的新类,它由question.java、mcq.java和twomarkq.java实现
根据hibernate文档
我们有3种选择。 InheritanceType.TABLE_PER_CLASS 或者 InheritanceType.SINGLE_TABLE 或者
InheritanceType.JOINED JOINED: 绝对不是我想要的。所以这是一个被排除的选择。

SINGLE_TABLE:

单表继承策略将所有子类只Map到一个数据库表,因此这也导致扩展基类的子类的联合。
我还有追随者

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

关于question.java、mcq.java和twomark.java

TABLE_PER_CLASS

“当使用多态查询时,需要一个联合来获取基类表以及所有子类表。”—因此这也是一个被排除的选项。
此外,我删除了表之间的外键引用。

相关问题