2012-11-05 5 views
1

나는 스프링 MVC, Hibernate4와 MySQL5와 몇 가지 간단한 웹 페이지를 만드는거야와 방울을 지속하는 동안. 내가 사용하는 모델 중 하나가 BLOB 값 (byte [])을 포함합니다. entityManager.persist() 으로 해당 모델을 유지하려고하면 MySQLSytnaxException이 발생합니다. 실제로 @Transactional 주석을 무시하고 persist/merge/remove 같은 현재 구성에 더 많은 문제가 있지만 가장 중요한 문제입니다. MySQLSyntaxErrorException 최대 절전 모드

는 이미 session.save(object);을 사용하여 또는 BLOB 바이트 [] 교체하려고. 여전히 같은 결과입니다. 내가 발견 한 모든 실제 사례는 완전히 다른 접근법을 사용합니다. 그들은 대신 JPA 것들의 HibernateSessionManager 및 HibernateTransactionManager를를 사용하는 - 그리고 나는 아직도 도움이 될 모르겠어요 때, 나는 개체를 유지하는 방법에 완전한 변화를 필요로하지 않는 솔루션을 발견하고 싶습니다. 내가 코드/구성/가정에서 만든 어떤 실수

당신은 말해 줄 수 있을까요?

스택의 시작은 최대 절전 모드 추적과 함께 추적 :

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] - [email protected] 
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 

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> 

Hibernate.properties : MySQL 데이터베이스에

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 

모든 테이블은 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() { 
    } 

    ... 
} 

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

편집 : Hibernate의 SessionFactory를에 EntityManagerManager 사용을 변경 - 내가 생각하는 것으로 변경하려 도움이 될 수 있습니다. 그것은하지 않았지만 코드는 조금 더 깨끗 해졌다 :). 도움이 될만한 Hibernate 로그의 정보를 추가했습니다. 또한이 에러는 Hibernate 구성과 관련된 것 같기 때문에 Hibernate.properties 콘텐트를 추가했다.

+0

생성 된 SQL 쿼리를 포함 할 수 있습니까? – david

+0

현재 할일이 많아서 찾을 수있는 최고의 내용은 다음과 같습니다. '최대 절전 : 업데이트 (변경, 추가, developmentVersion, filedata, filedataType, 메이저, 마이너, 야간, 릴리스, 패키지, 타입 - 불행히도 전체 SQL을 표시하기 전에 Spring을 구성 할 수 없었습니다. (예 : uploader, id) 나는 우선 순위가 높은 과제로 나아갈 필요가 있었으며 준비된 진술 (?)은 전혀 도움이되지 못했다. –

+0

찾을 수있는 정보를 추가하여 질문을 업데이트했습니다. –

답변

6

덕분에 내가 잘못 알아 볼 수있는 동료 개발자의 도움 : 나는 속성 중 하나의 이름으로 release을 사용하고 있었다. 나는 release이 MySQL의 키워드이며, 쿼리에 나타나면 구문이 유효하지 않음을 알게되었습니다.

나는 Hibernate가 열 ', 스키마'와 테이블의 이름에 아포스트로피를 사용하지 않는 것을 알고 솔직히 놀랐습니다. 나는 SQL 이런 식으로 작성하는 것이 일반적이라고 생각 :

INSERT INTO `mySqlTable` VALUES (null, 'value') ; 

또는

INSERT INTO 'dbo'.'msSqlTable' VALUES (null, 'value'); 

하지만 Hibernate는 그것을 대신 이런 식으로 할 것 : MySQL5를 들어

INSERT INTO mySqlTable VALUES (null, 'value') ; 

예약 목록을 단어가 상당히 길다. http://dev.mysql.com/doc/refman/5.0/en/reserved-words.html

나는 col을 선택하는 데 더주의해야 할 것 같다. 미래의 럼 이름. 희망은 누군가를 도울 것입니다.

+0

매우 흥미롭고, 업데이트를위한 thx – david