我正在使用 Spring MVC、Hibernate4 和 MySQL5 创建一些简单的网页。我使用的模型之一包含 BLOB 值(字节 [])。当我尝试使用该模型持久化时,entityManager.persist()
我得到 MySQLSytnaxException。实际上当前配置还有更多问题,例如忽略@Transactional注解的persist/merge/remove,但这是最关键的。
我已经尝试session.save(object);
通过 Blob 使用或替换 byte[]。结果还是一样。我发现的所有工作示例都使用完全不同的方法 - 例如,它们使用 HibernateSessionManager 和 HibernateTransactionManager 而不是 JPA 的 - 当我仍然不确定时,我想找到不需要完全改变我持久实体的解决方案有助于。
你能告诉我我在代码/配置/假设中犯了什么错误吗?
堆栈跟踪的开始以及 Hibernate 跟踪:
Hibernate:
insert
into
updates
(changelog, added, developmentVersion, filedata, filedataType, major, minor, nightly, release, package, type, uploader, id)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
22:53:10,888 TRACE BasicBinder:83 - binding parameter [1] as [VARCHAR] - sdfsd
22:53:10,891 TRACE BasicBinder:71 - binding parameter [2] as [DATE] - <null>
22:53:10,894 TRACE BasicBinder:83 - binding parameter [3] as [BOOLEAN] - false
22:53:10,898 TRACE BasicBinder:83 - binding parameter [4] as [BLOB] - javax.sql.rowset.serial.SerialBlob@298fd36c
22:53:10,924 TRACE BasicBinder:83 - binding parameter [5] as [VARCHAR] - image/png
22:53:10,926 TRACE BasicBinder:83 - binding parameter [6] as [INTEGER] - 1
22:53:10,928 TRACE BasicBinder:83 - binding parameter [7] as [INTEGER] - 0
22:53:10,935 TRACE BasicBinder:83 - binding parameter [8] as [INTEGER] - 0
22:53:10,936 TRACE BasicBinder:83 - binding parameter [9] as [INTEGER] - 0
22:53:10,939 TRACE BasicBinder:83 - binding parameter [10] as [INTEGER] - 36
22:53:10,941 TRACE EnumType:292 - Binding {0} to parameter: {1}
22:53:10,944 TRACE BasicBinder:83 - binding parameter [12] as [INTEGER] - 18
22:53:10,955 TRACE BasicBinder:83 - binding parameter [13] as [INTEGER] - 0
22:53:10,998 WARN SqlExceptionHelper:143 - SQL Error: 1064, SQLState: 42000
22:53:10,999 ERROR SqlExceptionHelper:144 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'release, package, type, uploader, id) values ('sdfsd', null, 0, _binary'‰PNG
' at line 1
22:53:11,027 INFO AbstractBatchImpl:195 - HHH000010: On release of batch it still contained JDBC statements
Nov 07, 2012 10:53:11 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [repoApplication] in context with path [/server] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'release, package, type, uploader, id) values ('sdfsd', null, 0, _binary'‰PNG
' at line 1; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'release, package, type, uploader, id) values ('sdfsd', null, 0, _binary'‰PNG
' at line 1] with root cause
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'release, package, type, uploader, id) values ('sdfsd', null, 0, _binary'‰PNG
' at line 1
豆类.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
...
>
...
<!-- Hibernate configuration -->
<!-- Specifies dataSource object managing connections to database -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
</bean>
<!-- Defines SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
...
<property name="hibernateProperties">
<util:properties location="classpath:Hibernate.properties" />
</property>
</bean>
<!-- Defines TransactionManager -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- Binds TransactionManager to annotations -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- Enables Spring annotations -->
<context:annotation-config />
...
</beans>
休眠.属性:
hibernate.database =MYSQL
hibernate.dialect =org.hibernate.dialect.MySQL5InnoDBDialect
hibernate.show_sql =true
hibernate.format_sql =true
hibernate.use_sql_comments =true
hibernate.hbm2ddl.auto =update
MySQL 数据库中的所有表都使用 InnoDB 引擎。
更新.java(模型):
import java.sql.Blob;
import java.sql.Date;
import java.sql.SQLException;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.sql.rowset.serial.SerialBlob;
import javax.validation.constraints.NotNull;
import org.hibernate.annotations.Type;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
...
@Entity
@Table(name = "updates")
@VersionNumberCorrect
public class Update {
@Id
@Column(name = "id", unique = true)
private int id;
@NotNull
@ManyToOne
@JoinColumn(name = "package")
private Package thePackage;
@NotNull
@ManyToOne
@JoinColumn(name = "uploader")
private User uploader;
@Column(name = "added")
private Date date;
@Column(name = "changelog")
@NotNull
@NotEmpty
private String changelog;
@Column(name = "major")
private int major;
@Column(name = "minor")
private int minor;
@Column(name = "release")
private int release;
@Column(name = "nightly")
private int nightly;
@Column(name = "developmentVersion")
private boolean developmentVersion;
@Column(name = "type")
@Enumerated(EnumType.ORDINAL)
private EUpdateStrategy type;
@Column(name = "filedata")
@Lob
@Type(type = "blob")
@NotNull
private Blob filedata;
@Column(name = "filedataType")
private String filedataType;
public Update() {
}
...
}
UpdateServiceImp.java(服务):
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
...
@Service
@Transactional
public class UpdateServiceImp implements UpdateService {
@Autowired
private SessionFactory sessionFactory;
@Override
public void persist(Update update) {
getSession().persist(update);
}
@Override
public Update merge(Update update) {
return (Update) getSession().merge(update);
}
@Override
public void remove(Update update) {
getSession().delete(update);
}
...
/**
* Returns new Session instance.
*
* @return new Session
*/
private Session getSession() {
return sessionFactory.getCurrentSession();
}
}
编辑:我将 EntityManagerManager 的用法更改为 Hibernate 的 SessionFactory - 我试图改变这种想法,它可能会有所帮助。它没有,但是代码变得更干净了:)。我从 Hibernate 日志中添加了一些可能有用的信息。我还添加了 Hibernate.properties 内容,因为这个错误很可能与 Hibernate 配置有关。