用于Hibernate的SQLLite方言,表没有映射错误

时间:2016-08-03 16:04:30

标签: java hibernate sqlite

我目前正在使用JavaFX开发应用程序,并且我使用带有sqlite-jdbc-3.8.11.2连接器的SQLLite数据库,而且对于我的ORM模型,我选择了最新的Hibernate发行版。我遇到的问题是,我无法执行由我编写的查询,尽管我已成功设法从数据库中插入,读取,更新和删除,但我无法在不使用默认值的情况下执行此操作来自Hibernate的操作。 这些是我在hibernate.cfg.xml文件中的配置设置:

<!-- JDBC Database Connection Settings-->      
        <property name="connection.driver_class">org.sqlite.JDBC</property>
        <property name="connection.url">jdbc:sqlite:database.db</property>
        <!-- JDBC Connection Pool Settings-->
        <property name="connection.pool_size">1</property>
        <!-- Selecting SQL Dialect-->
        <property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>
        <!-- Echo the SQL to stdout-->
        <property name="show_sql">true</property>
        <!-- Set the current session context -->
        <property name="current_session_context_class">thread</property>

正如您所看到的,我在这个数据库中使用HSQL Dialect,这是因为我无法在Hibernate框架提供的包中找到sqlite方言。但是,正如我之前所说,它以某种方式起作用。

所以我有一个名为Program的类,它实际上是一个名为Programs的数据库中的表。以下是Java代码中Program的定义:

public class Program {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "program_id")
    protected int program_id;

    @Column(name = "name")
    protected String name;
    @Column(name = "developer")
    protected String developer;
    @Column(name = "rating")
    protected int rating;
    @Column(name = "state")
    protected int state;
    @Column(name = "reservation_date")
    protected String reservedDate;
    @Column(name = "sent_date")
    protected String sentDate;

    public Program() {
    }

    public Program(String name, int state, LocalDate reservation_date) {
        this.name = name;
        this.state = state;
        this.reservedDate = reservation_date.toString();
    }

现在我有另一个名为DatabaseConnector的类,用于管理数据库连接。这是它的代码:

public class DatabaseConnector {
    private final SessionFactory sessionFactory;

    public DatabaseConnector() {
        sessionFactory = new Configuration()
                .configure()
                .addAnnotatedClass(Program.class)//adding table
                .buildSessionFactory();
    }

    public Program getProgram(int id) {
        Session session = sessionFactory.getCurrentSession();
        session.beginTransaction();
        Program p = session.get(Program.class, id);//captures an object from the database
        session.getTransaction().commit();
        return program;
    }

正如您在上面看到的那样,有一个完美的getProgram()方法。

但是,当我尝试执行自己的查询时,基于Hibernate文档,它应该是这样的:

public Program getProgram(int id) {
        Session session = sessionFactory.getCurrentSession();
        session.beginTransaction();
        List<Program> p = session.createQuery("FROM Programs WHERE   Programs.id="+id).list();//This should find an Program
        session.getTransaction().commit();
        return p.get(0);
    }

这是Hibernate显示的错误:

  java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Programs is not mapped [FROM Programs WHERE Programs.id=1]

我必须说这个错误不仅发生在SELECT操作上,而且我尝试用我自己的个人Query执行的每个操作。我相信这个错误与数据库方言有关,但我不太确定。

2 个答案:

答案 0 :(得分:0)

我认为没有理由相信这与方言有关。你的HQL不正确。您的查询应该是

"FROM Program p WHERE   p.id="+id

(注意Program,类名,而不是Programs,表名。)

更好的是,在查询中使用参数:

List<Program> p = session.createQuery("FROM Program p WHERE p.id=:id")
         .setParameter("id", id)
         .list();

或者,由于您正在通过名为id的字段进行选择,因此您可能希望列表中包含单个结果:

 Program p = session.createQuery("FROM Program p WHERE p.id=:id")
         .setParameter("id", id)
         .uniqueResult();

答案 1 :(得分:0)

你要解决的第一件事就是方言。网上有不同的解决方案。我会尝试这个:

<dependency>
   <groupId>net.kemitix</groupId>
   <artifactId>sqlite-dialect</artifactId>
   <version>0.1.0</version>
</dependency> 

依赖包含org.hibernate.dialect.SQLiteDialect,看起来非常合理。但我自己没有测试过。 听听它是如何成功的会很有趣!