我目前正在使用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执行的每个操作。我相信这个错误与数据库方言有关,但我不太确定。
答案 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
,看起来非常合理。但我自己没有测试过。
听听它是如何成功的会很有趣!