Apache Tomcat(v6.0)で実行される標準のSpring Framework(v3.1.2)java(v1.6)データベースに裏打ちされた(postgres v9.1)Webアプリケーションがあります。Hibernate 3.6.10.Final and Spring DataJPA1.2.0.RELEASEを使用していることに注意してください。
2つのデータベースエンティティクラス(ChapterとChapterText)があり、それらの間には1対1の関係があります...
@Entity @Table(name="chapter")
public class Chapter implements Comparator<Chapter> {
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="CHAPTER_SEQ")
@SequenceGenerator(name="CHAPTER_SEQ", sequenceName="chapter_seq", allocationSize=1)
@Column(name="id")
private Long id;
@OneToOne(cascade=CascadeType.ALL, optional=false, fetch=FetchType.LAZY, orphanRemoval=true) @PrimaryKeyJoinColumn
private ChapterText chapterText;
// other properties plus setters and getters
}
@Entity @Table(name="chapterText")
public class ChapterText {
@Id
@GeneratedValue(generator="foreign")
@GenericGenerator(name="foreign", strategy="foreign", parameters={ @Parameter(name="property", value="parent") })
@Column(name="id")
private Long id;
@OneToOne(mappedBy="chapterText", optional=false)
private Chapter parent;
@Column(name="body") @Lob
private String body;
// setters and getters
}
ここで、ChapterTextには大量のテキストを保持できる可能性のある@Lobプロパティが含まれているため、ChapterクラスでchapterTextプロパティをマークして、遅延ロードされるようにしました。
OpenEntityManagerInViewFilterをセットアップして構成したので、モデルにチャプターエンティティ(「chapter」という名前)を追加できます。その後、JSPXファイルでこれを実行できるはずです...
${chapter.chapterText.body}
これにより、ChapterTextエンティティが遅延ロードされ、呼び出し元のブラウザ用に生成されたXHTMLページにbodyプロパティの値が含まれるはずです。
これは、私が何年も使用しているデータベースからの情報を表示するための非常に標準的な方法です。ただし、Postgresで@Lobプロパティを使用する必要があったのはこれが初めてです。これを行うと、次のスタックトレースが表示されます...
org.apache.jasper.JasperException: javax.servlet.ServletException: javax.servlet.jsp.JspException: javax.servlet.jsp.JspException: javax.el.ELException: Error reading 'body' on type project.vo.db.ChapterText_$$_javassist_5
.
.
.
javax.servlet.ServletException: javax.servlet.jsp.JspException: javax.servlet.jsp.JspException: javax.el.ELException: Error reading 'body' on type project.vo.db.ChapterText_$$_javassist_5
.
.
.
javax.servlet.jsp.JspException: javax.el.ELException: Error reading 'body' on type project.vo.db.ChapterText_$$_javassist_5
.
.
.
javax.el.ELException: Error reading 'body' on type project.vo.db.ChapterText_$$_javassist_5
.
.
.
org.hibernate.exception.GenericJDBCException: could not load an entity: [project.vo.db.ChapterText#1]
.
.
.
org.postgresql.util.PSQLException: Large Objects may not be used in auto-commit mode.
私が見つけたものから、Posgresは、自動コミットがfalseに設定されたトランザクションを介してアクセスされるラージオブジェクトにアクセスする必要があります。
厄介なことに、これを回避するために私が考えることができた唯一のアプローチは、@ Lobプロパティをフェッチし、@ Transactionalでマークし、表示目的で特別に作成されたBeanに値をロードするリポジトリメソッドを作成することです。それは機能しますが、少しエレガントではないようです。
誰かが別のアプローチのアイデアを持っていますか?