티스토리 툴바


org.hibernate.AnnotationException: referencedColumnNames(columnName) of A... referencing B... not mapped to a single property
at org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.java:180)
at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:88)
at org.hibernate.cfg.AnnotationConfiguration.processEndOfQueue(AnnotationConfiguration.java:456)
at org.hibernate.cfg.AnnotationConfiguration.processFkSecondPassInOrder(AnnotationConfiguration.java:438)
at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:309)
at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1134)
at org.hibernate.ejb.Ejb3Configuration.buildMappings(Ejb3Configuration.java:1226)
at org.hibernate.ejb.EventListenerConfigurator.configure(EventListenerConfigurator.java:173)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:854)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:425)

Hibernate/JPA로 개발하는 도중 위의 에러가 발생하여 원인을 찾았는데 그 원인이 너무 사소한 실수로 인한 것이어서 포스팅을 한다.

일단 에러의 내용을 살펴보면 
  B...를 참조하는 A...의 참조컬럼이 단일속성으로 매핑되지 않는다. 
로 해석된다. 즉, 하나의 컬럼으로는 FK를 선언할 수 없다는 내용으로 이해하면 되며 결국 PK가 하나가 아니라는 말이된다.

위의 내용만을 본다면 @IdClass 나 @EmbeddedId 로 선언하여 단일키가 아닌 복합키로 PK를 선언했어야 했는데 아래와 같이 단일키로 생성했다. 

그런데 자세히 보면 이 도메인객체는 그 자체로 문제가 있다. 왜냐하면 @Id 선언이 두개가 되어 있기 때문이다.(붉은색 굵은 글씨 참고)
나중에 해결했을 땐 너무 어이없었지만 Copy&Paste 를 하는 과정에서 이런 실수를 할 수도 있을 것 같다. 아무쪼록 이글이 나와 같은 상황에서 빠른 문제해결이 될 수 있도록 도움이 되었으면 한다.

B:
@Entity
@Table(name = "TT_TROUBLE_TICKET")
public class TroubleTicket implements Serializable {

    /** UID */
    private static final long serialVersionUID = -6144092108662486502L;

    /** 장애아이디 */
    @Id
    @GeneratedValue(generator = "SQ_TT_TROUBLE_TICKET")
    @SequenceGenerator(name = "SQ_TT_TROUBLE_TICKET", initialValue = 1, allocationSize = 1, sequenceName = "SQ_TT_TROUBLE_TICKET")
    @Column(name = "TROUBLE_TICKET_ID", nullable = false)
    private long troubleTicketId;

    /** 샵아이디 */
    @Id // 제거해야함
    @Column(name = "SHOP_ID", length = 8)
    private String shopId;

}

A:
@Entity
@Table(name = "TT_COMMENT")
public class TroubleTicketComment implements Serializable {

    /** UID */
    private static final long serialVersionUID = 765699083453512999L;

    /** 조치내역아이디 */
    @Id
    @GeneratedValue(generator = "SQ_TT_COMMENT")
    @SequenceGenerator(name = "SQ_TT_COMMENT", initialValue = 1, allocationSize = 1, sequenceName = "SQ_TT_COMMENT")
    @Column(name = "COMMENT_ID", nullable = false)
    private long commentId;

    /** 장애 */
    @ManyToOne
    @JoinColumn(name = "TROUBLE_TICKET_ID", referencedColumnName = "TROUBLE_TICKET_ID", nullable = false)
    private TroubleTicket troubleTicket;
}



저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License
JPA구현을 Unitils + DBUnit으로 테스트를 수행할 때 다음과 같은 에러가 발생한 경우
DBUnit이 초기화하는 테이블의 순서에 주의해야한다.
즉, A OneToMany B, C OneToMany B 와 같이 정의한 경우 A, C, B 순서로 정의해야만한다.
이때 DBUnit은 A, C, B의 순서로 데이터를 로드하고 B, C, A의 순서로 클리어한다.
그런나 만약 B를 C앞에 정의하게 되면 다시말해 A, B, C의 순서로 정의하면 삭제할 때 아래와 같은 제약사항 오류를 보게된다.


Caused by: org.unitils.core.UnitilsException: Error while executing DataSetLoadStrategy
at org.unitils.dbunit.datasetloadstrategy.impl.BaseDataSetLoadStrategy.execute(BaseDataSetLoadStrategy.java:48)
at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:230)
at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:153)
... 22 more
Caused by: java.sql.SQLException: Integrity constraint violation FK1258F61560459CB5 table: CU_SHOP_EXTRA_CONTACT
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.jdbcStatement.fetchResult(Unknown Source)
at org.hsqldb.jdbc.jdbcStatement.execute(Unknown Source)
at org.dbunit.database.statement.SimpleStatement.executeBatch(SimpleStatement.java:67)
at org.dbunit.operation.DeleteAllOperation.execute(DeleteAllOperation.java:125)
at org.dbunit.operation.CompositeOperation.execute(CompositeOperation.java:78)
at org.unitils.dbunit.datasetloadstrategy.impl.CleanInsertLoadStrategy.doExecute(CleanInsertLoadStrategy.java:45)
at org.unitils.dbunit.datasetloadstrategy.impl.BaseDataSetLoadStrategy.execute(BaseDataSetLoadStrategy.java:44)
... 24 more
저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

log4j:WARN Please initialize the log4j system properly. 해결방법

2010/02/11 22:22 | Posted by 포데브(엄지사랑) 엄지사랑
웹애플리케이션을 구현하다보면 로그는 정상적으로 나오는데 아래와 같은 경고(WARN)을 볼때가 있다. 사실 동작하는데 지장을 주는 것은 아니지만 나의 지론
"경고를 무시하지 말라!" 에 따라서 해결방법을 찾아보았다.

log4j:WARN No appenders could be found for logger (org.springframework.web.context.ContextLoader).
log4j:WARN Please initialize the log4j system properly.

이럴땐 아래와 같이 WEB-INF/web.xml 에서 붉은 색으로 표시한 부분과 같은 순서로 되어 있는지 확인한다. 즉, Log4J를 먼저 선언하면 위와 같은 경고는 없어진다.
  
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_NexfaAdminWeb" version="2.5"
  xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

  <display-name>NexfaApiWeb</display-name>

  <context-param>
    <param-name>webAppRootKey</param-name>
    <param-value>nexfa.apiweb</param-value>
  </context-param>

  <context-param>
    <param-name>log4jConfigLocation</param-name>
    <param-value>/WEB-INF/log4j.properties</param-value>
  </context-param>

  <context-param>
    <param-name>log4jRefreshInterval</param-name>
    <param-value>5000</param-value>
  </context-param>
  
  
<listener>
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
  </listener>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
</web-app>
저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

struts OGNL에서 static method 사용하기

2010/01/18 16:24 | Posted by 포데브(엄지사랑) 엄지사랑
사실 포스팅 하기에는 너무 간다한한 내용이라 망설여지긴 하지만 알면 간단하나 모르면 너무 어려운것이므로...^^;

<constant name="struts.ognl.allowStaticMethodAccess" value="true" />

와 같이 한줄을 struts.xml 이나 struts.properties 에 추가해 주면 된다.
그리고 <s:property value="@class.full.name@staticMethodName()"/>와 같이 사용하면 된다. 사실 정적메소드 접근에 대한 기본값이 false 이므로 


에서 설명하는 내용이 동작하지 않는 것처럼 보이고 이런 내용이 인터넷 상에 다수 보이고 있다. ㅋㅋ 사실 나도 왜 안나오나 하고 순간 당황 ^^;

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

struts에서 ContextPath 사용하기

2010/01/18 15:17 | Posted by 포데브(엄지사랑) 엄지사랑

"올바른 성장과 따뜻한 나눔"

<s:set name="ctx">${pageContext.request.contextPath}</s:set>
1. [${ctx}]
2. [<s:property value="%{#ctx}" />]
3. [<s:property value="#ctx" />]

참간단해 보이지만 또 막상 사용하려고 하면 서핑을 하게 됩니다.

또한 거의 대부분 ${pageContext.request.contextPath}와 같은 방식만 언급되어 있지 변수로 선언하고 설정한 다음 사용하는 방법에 대해서는 언급이 없습니다.

그래서 간단하게 접근하기 위한 방법을 공유합니다.

위에서 3가지 방법으로 접근하는 방법을 소개하고 있는데 ${}방식은 프리마커 스타일이구요

밑에 두가지 방식은 OGNL 방식입니다.

(결과는 같지만 %{}는 non-String 일때 문자열로 분석하게 하는 기능입니다. 여기서는 필요가 없죠?..  ㅎㅎ

그래도 이런 표현도 있다는 것을 알아 두세요. 문자열이 아닌 값을 출력할 때는 반드시 써야합니다.^^;

참고: http://struts.apache.org/2.0.14/docs/tag-syntax.html)

OGNL에서는 프리마커스타일을 사용할 수 없기 때문에 첫 문장처럼 태그의 바디문자열로 접근해야만 합니다.

유용한 정보가 되었으면 하네요^^;

끝.

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

HttpClient의 GetMethod 사용시 URL의 한글처리

2008/04/04 21:17 | Posted by 포데브(엄지사랑) 엄지사랑

GetMethod 사용시 [코드1]과같이 URL을 생성하고 실행하면 [코드2]와 같은 예외가 발생한다.
    

[코드1]

        // Create a method instance.
        StringBuilder searchURL = new StringBuilder(this.urlRoot + "/term/search.json");
        searchURL.append('?').append("dictionaryId").append('=').append(dictionary.getId());
        searchURL.append('&').append("queryString").append('=').append(queryString);
        searchURL.append('&').append("start").append('=').append(0);
        GetMethod httpMethod = new GetMethod(searchURL.toString());


 

[코드2]

java.lang.IllegalArgumentException: Invalid uri 'http://localhost:8080/bcf/term/search.json?dictionaryId=6&queryString=윤*&start=0': Invalid query
 at org.apache.commons.httpclient.HttpMethodBase.<init>(HttpMethodBase.java:222)
 at org.apache.commons.httpclient.methods.GetMethod.<init>(GetMethod.java:89)
 at kr.nextree.nexdic.facade.DictionaryFacade.searchTerms(DictionaryFacade.java:175)
 at kr.nextree.nexdic.facade.DictionaryFacadeTest.testSearchTerm(DictionaryFacadeTest.java:68)

이를 해결하기위해서는 [코드3]과 같이 인코딩되어야할 파라메터값은 인코딩을 해준다.

[코드3]

        try {
            queryString = URLEncoder.encode(queryString, "UTF-8");
        }
        catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
크리에이티브 커먼즈 라이선스
Creative Commons License

JSON Tools 사용기

2008/04/04 11:16 | Posted by 포데브(엄지사랑) 엄지사랑
Home : http://jsontools.berlios.de/

1. 간단소개 : JSON(JavaScript Object Notation) 을 자바객체로 변환하는 기능 또는 그 반대의 기능을 제공한다.

2. 주요기능:
1) Parser : JSON 텍스트 파일을 분석(Parse)하여 자바모델로 변환(Convert)한다.
2) Renderer : Java 표현을 테스트로 제공(Render)한다.
3) Serializer : POJO를 JSON 표현으로 직렬화(Serialize)한다. 목적은 모든 종류의 자바 데이터구조(재귀, 참조, 원시타입, ...)를 처리할 수 있는 직렬화(serializing) 매커니즘을 제공하는 것이다.
4) Mapper : POJO와 JSON을 맵핑(Map)한다. 이때 JSON 텍스트는 가능한 명료해야만한다. 이 툴은 자바와 JSON을 분석해야하는 다른 프로그래밍 언어가 데이터로 통신할 때 최적의 선택을 한다.
5) Validator : JSON 스키마를 사용하여 JSON 파일의 내용을 검증(Validate)한다.

3. 필요(의존)라이브러리:
- antlr-2.7.6-2005-12-23.jar

4. 총평
비교적 사용하기가 쉽다. 그러나 그다지 유연하지 못하다는 단점이 있는듯 하다. 자바의 인트로스펙션을 사용하여 맵핑하기 때문에 만약 JSON 문자열에 숫자로만 되어 있는 데이터가 있다면 POJO에서 Number 가 아닌 타입이 선언되어 있다면 에러가 발생한다. 문제는 일반 문자열인데 가끔 숫자형 문자열이 있을 경우이다. 이때는 해결책이 보이지 않는다.

가장 큰문제점은 아직 사용자가 많지 않아서 인지 문서가 많이 부족하며 적용사례가 없고 문제를 해결하기가 쉽지 않다는 것이다.

그럼에도 간단한 경우에는 비교적 사용하기 쉽기때문에 사용할만 하다.
크리에이티브 커먼즈 라이선스
Creative Commons License

Content-Type 정리

2008/03/19 19:42 | Posted by 포데브(엄지사랑) 엄지사랑


contentType

application/acad
AutoCAD drawing files
dwg

application/clariscad
ClarisCAD files
ccad

application/dxf
DXF (AutoCAD)
dxf

application/msaccess
Microsoft Access file
mdb

application/msword
Microsoft Word file
doc

application/octet-stream
Uninterpreted binary
bin

application/pdf
PDF (Adobe Acrobat)
pdf

application/postscript-x
PostScript-x, encapsulated PostScript-x,
Adobe Illustrator
ai, ps, eps

application/rtf
Rich Text Format file
rtf rtf

application/vnd.ms-excel
Microsoft Excel file
xls

application/vnd.ms-powerpoint
Microsoft PowerPoint file
ppt

application/x-cdf
Channel Definition Format file
cdf

application/x-csh
C-shell script-x
csh csh

application/x-dvi
TeX
dvi dvi dvi

application/x-javascript-x
JavaScript-x source file
js

application/x-latex
LaTeX source file
latex

application/x-mif
FrameMaker MIF format
mif

application/x-msexcel
Microsoft Excel file
xls

application/x-mspowerpoint
Microsoft PowerPoint file
ppt

application/x-tcl
TCL script-x
tcl

application/x-tex
TeX source file
tex

application/x-texinfo
Texinfo (emacs)
texinfo, texi

application/x-troff
troff file
t, tr, roff t, tr, roff

application/x-troff-man
troff with MAN macros
man

application/x-troff-me
troff with ME macros
me

application/x-troff-ms
troff with MS macros
ms

application/x-wais-source
WAIS source file
src

application/zip
ZIP archive
zip

audio/basic
Basic audio (usually m-law)
au, snd

audio/x-aiff
AIFF audio
aif, aiff, aifc

audio/x-wav
Windows WAVE audio
wav

image/gif
GIF image
gif

image/ief
Image Exchange Format file
ief

image/jpeg
JPEG image
jpeg, jpg jpe

image/tiff
TIFF image
tiff, tif

image/x-cmu-raster
CMU Raster image
ras

image/x-portable-anymap
PBM Anymap image format
pnm

image/x-portable-bitmap
PBM Bitmap image format
pbm

image/x-portable-graymap
PBM Graymap image format
pgm

image/x-portable-pixmap
PBM Pixmap image format
ppm

image/x-rgb
RGB image format
rgb

image/x-xbitmap
X Bitmap image
xbm

image/x-xpixmap
X Pixmap image
xpm

image/x-xwindowdump
X Windows Dump (xwd)
xwd

multipart/x-gzip
GNU ZIP archive
gzip

multipart/x-zip
PKZIP archive
zip

text/css
Cascading style sheet
css

text/html
HTML file
html, htm

text/plain
Plain text
txt

text/richtext
MIME Rich Text
rtx

text/tab-separated- values
Text with tab-separated values
tsv

text/xml
XML document
xml

text/x-setext
Struct-Enhanced text
etx

text/xsl
XSL style sheet
xsl

video/mpeg
MPEG video
mpeg, mpg, mpe

video/quicktime
QuickTime video
qt, mov

video/x-msvideo
Microsoft Windows video
avi

video/x-sgi-movie
SGI movie player format
movie


JSP에서 강제 파일다운로드 트릭
<%
    response.setHeader("Content-Type", "application/x-msdownload");
    response.setHeader("Content-Disposition", "attachment;filename=파일명;");
%>


크리에이티브 커먼즈 라이선스
Creative Commons License
이전 1 다음