Mat*_*zok 1 mysql hibernate jpa blob spring-mvc
我正在使用Spring MVC,Hibernate4和MySQL5创建一些简单的网页.我使用的模型之一包含BLOB值(byte []).当我尝试坚持该模型时,entityManager.persist()
我得到了MySQLSytnaxException.实际上当前配置存在更多问题,例如persist/merge/remove忽略@Transactional注释,但这个问题是最关键的.
我已经尝试过使用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
Run Code Online (Sandbox Code Playgroud)
beans.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>
Run Code Online (Sandbox Code Playgroud)
Hibernate.properties:
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
Run Code Online (Sandbox Code Playgroud)
MySQL数据库中的所有表都使用InnoDB引擎.
Update.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() {
}
...
}
Run Code Online (Sandbox Code Playgroud)
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();
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:我将EntityManagerManager用法改为Hibernate的SessionFactory - 我试图改变它认为它可能会有所帮助.它没有,但代码有点干净:).我在Hibernate日志中添加了一些可能有用的信息.我还添加了Hibernate.properties内容,因为这个错误很可能与Hibernate配置有关.
感谢一位开发人员的帮助,我发现了什么是错的:我用它release作为其中一个属性的名称.我发现这release是MySQL中的一个关键字,当它出现在查询中时,它会使语法无效.
我真的很惊讶地发现Hibernate没有使用带有列',schemas'和table'名称的撇号.我认为以这种方式编写SQL是一种常见的做法:
INSERT INTO `mySqlTable` VALUES (null, 'value') ;
Run Code Online (Sandbox Code Playgroud)
要么
INSERT INTO 'dbo'.'msSqlTable' VALUES (null, 'value');
Run Code Online (Sandbox Code Playgroud)
但是Hibernate会这样做:
INSERT INTO mySqlTable VALUES (null, 'value') ;
Run Code Online (Sandbox Code Playgroud)
对于MySQL5,保留字列表很长:http://dev.mysql.com/doc/refman/5.0/en/reserved-words.html
我想我将来必须更加小心选择列名.希望能帮到别人.
| 归档时间: |
|
| 查看次数: |
2911 次 |
| 最近记录: |