봄, 동면, 블랍 게으른 로딩
Hibernate에서 게으른 blob 로딩에 도움이 필요합니다.웹 애플리케이션에는 다음과 같은 서버와 프레임워크가 있습니다.MySQL, Tomcat, Spring and Hibernate.
데이터베이스 구성의 부분입니다.
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="driverClass" value="${jdbc.driverClassName}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="initialPoolSize">
<value>${jdbc.initialPoolSize}</value>
</property>
<property name="minPoolSize">
<value>${jdbc.minPoolSize}</value>
</property>
<property name="maxPoolSize">
<value>${jdbc.maxPoolSize}</value>
</property>
<property name="acquireRetryAttempts">
<value>${jdbc.acquireRetryAttempts}</value>
</property>
<property name="acquireIncrement">
<value>${jdbc.acquireIncrement}</value>
</property>
<property name="idleConnectionTestPeriod">
<value>${jdbc.idleConnectionTestPeriod}</value>
</property>
<property name="maxIdleTime">
<value>${jdbc.maxIdleTime}</value>
</property>
<property name="maxConnectionAge">
<value>${jdbc.maxConnectionAge}</value>
</property>
<property name="preferredTestQuery">
<value>${jdbc.preferredTestQuery}</value>
</property>
<property name="testConnectionOnCheckin">
<value>${jdbc.testConnectionOnCheckin}</value>
</property>
</bean>
<bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="/WEB-INF/hibernate.cfg.xml" />
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
</props>
</property>
<property name="lobHandler" ref="lobHandler" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
엔터티 클래스의 부분
@Lob
@Basic(fetch=FetchType.LAZY)
@Column(name = "BlobField", columnDefinition = "LONGBLOB")
@Type(type = "org.springframework.orm.hibernate3.support.BlobByteArrayType")
private byte[] blobField;
문제 설명입니다.MySQL 데이터베이스에 저장된 파일과 관련된 웹 페이지 데이터베이스 기록을 표시하려고 합니다.데이터 볼륨이 작으면 모두 정상적으로 작동합니다.의 양이 많아요 데터이무서다가다가데t서터r무ne이cgesm' .java.lang.OutOfMemoryError: Java heap space
테이블의 각 행에 blobFields null 값을 적으려고 했습니다.이 경우 애플리케이션이 정상적으로 작동하고 메모리가 꺼지지 않습니다.나는에 대한 고된에다한을다을에한ih고enbsta@Basic(fetch=FetchType.LAZY)
게으르지 않아요!
저는 혼란스러워요.엠마누엘 버나드는 ANN-418에서 다음과 같이 썼습니다.@Lob
다,).@Basic(fetch = FetchType.LAZY)
주석).
는 의 는 을 합니다 합니다 을 는 의 @Lob
모든 드라이버/파일럿과 함께 작동하지 않습니다.
일부 사용자는 바이트코드 계측(javassit?)을 사용할 때 작동한다고 보고합니다.cglib?).
하지만 이 모든 것에 대한 명확한 언급을 문서에서 찾을 수 없습니다.
마지막으로 권장되는 해결 방법은 속성 대신 "가짜" 일대일 매핑을 사용하는 것입니다. 기존 클래스에서 LOB 필드를 제거하고 동일한 테이블, 동일한 기본 키 및 필요한 LOB 필드만 속성으로 참조하는 새 클래스를 만듭니다. 매핑을 일대일, fetch="select", lazy="true"로 지정합니다. 부모 개체가 세션에 있는 한 원하는 것을 정확하게 얻어야 합니다.(이것을 주석으로 바꿔치기만 하면 됩니다).
게으른 속성을 로드하려면 빌드 시간 바이트 코드 계측이 필요합니다.
바이트코드 계측을 피하려면 하나의 옵션은 동일한 테이블을 사용하는 두 개의 엔티티를 생성하는 것입니다. 하나는 블롭이 없는 엔티티입니다.그럼 blob이 필요할 때만 blob이 있는 엔티티를 사용하세요.
이 시나리오를 처리하기 위해 상속을 사용할 것을 제안합니다.blob이 없는 기본 클래스와 바이트 배열을 포함하는 파생 클래스가 있습니다.파생 클래스는 UI에 blob을 표시해야 할 경우에만 사용합니다.
물론 이 값을 추출하여 "@OneToOne" 관계가 있는 새 테이블에 입력할 수도 있지만, 애플리케이션에서는 이 구성만 사용하여 LOB가 필요에 따라 느리게 로드됩니다.
@Lob
@Fetch(FetchMode.SELECT)
@Type(type="org.hibernate.type.PrimitiveByteArrayBlobType")
byte[] myBlob;
이것은 Postgre에서 동시에 우리 프로젝트에서 테스트됩니다.SQL, MySQL, SQL Server 및 Oracle을 사용하므로 사용자에게 적합합니다.
저도 같은 문제가 있었는데, 이 문제가 제 해결책이었습니다.
내 엔티티:
@Entity
@Table(name = "file")
public class FileEntity {
@Id
@GeneratedValue
private UUID id;
@NotNull
private String filename;
@NotNull
@Lob @Basic(fetch = FetchType.LAZY)
private byte[] content;
...
pom.xml에 플러그인 추가:
<plugin>
<groupId>org.hibernate.orm.tooling</groupId>
<artifactId>hibernate-enhance-maven-plugin</artifactId>
<executions>
<execution>
<phase>compile</phase>
<configuration>
<failOnError>true</failOnError>
<enableLazyInitialization>true</enableLazyInitialization>
</configuration>
<goals>
<goal>enhance</goal>
</goals>
</execution>
</executions>
</plugin>
저는 게으른 부하는 컴파일한 다음 실행하는 방식으로만 작동했고, 예를 들어 일식이나 인텔라이에서는 작동하지 않았습니다.
그래들을 사용하다가 작동시키기 위해 다음과 같이 했습니다.
- 도면요소 주석 달기
- 최대 절전 모드 그라들 플러그인 설정
빌드.그레이들
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.hibernate:hibernate-gradle-plugin:5.4.0.Final"
}
}
apply plugin: 'java'
apply plugin: 'application'
apply plugin: 'org.hibernate.orm'
hibernate {
enhance {
enableLazyInitialization = true
enableDirtyTracking = true
enableAssociationManagement = true
}
}
엔티티.자바
@Entity
public class Person {
@Id
@GeneratedValue
private Integer id;
@Lob
@Basic(fetch = FetchType.LAZY)
@Column(length = 255, nullable = false)
private String name;
테스트
./gradlew run
사용하면 게으른 로딩이 가능합니다.Blob
대신 타자를 치다byte[]
.
@Column(name = "BlobField", nullable = false)
@Lob
@Basic(fetch = FetchType.LAZY)
private Blob blobField;
이 필드는 느리게 로드되며 값을 검색해야 하는 경우 이 필드에 액세스할 수 있습니다.
String value = IOUtils.toByteArray(entity.getBlobField().getBinaryStream());
@MohammadRezaAlagheband(나의 경우 @Basic(fetch=lazy @))의 응답을 기반으로 @OneTone 표기법을 사용하는 간단한 작업대는 다음과 같습니다.
@Getter
@Setter
@Entity
@Table(name = "document")
@AllArgsConstructor
@NoArgsConstructor
public class DocumentBody implements java.io.Serializable{
@Column(name = "id", insertable = false)
@ReadOnlyProperty
@Id
@PrimaryKeyJoinColumn
private Integer id;
@Column(name = "body", unique = true, nullable = false, length = 254)
@JsonView({JSONViews.Simple.class, JSONViews.Complete.class})
private String content;
}
@Getter
@Entity
@Setter
@Table(name = "document")
@AllArgsConstructor
@NoArgsConstructor
public class DocumentTitle implements java.io.Serializable{
@Column(name = "id", insertable = false)
@ReadOnlyProperty
@Id
private Integer id;
@Column(name = "title", unique = true, nullable = false, length = 254)
@JsonView({JSONViews.Simple.class, JSONViews.Complete.class})
private String content;
}
public class Document implements java.io.Serializable {
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
@JsonView({JSONViews.Simple.class, JSONViews.Complete.class})
private Integer id;
//Also it is posssible to prove with @ManyToOne
@OneToOne(fetch = FetchType.LAZY, optional = false, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
@JoinColumn(name = "id", referencedColumnName = "id", nullable = false)
@JsonView({JSONViews.Simple.class, JSONViews.Complete.class})
private DocumentTitle title;
@OneToOne(fetch = FetchType.LAZY, optional = false, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
@JoinColumn(name = "id", referencedColumnName = "id", nullable = false)
@JsonView({JSONViews.Simple.class, JSONViews.Complete.class})
private DocumentBody body;
}
언급URL : https://stackoverflow.com/questions/2605477/spring-hibernate-blob-lazy-loading
'source' 카테고리의 다른 글
glibc의 감가상각 __malloc_hook 기능에 대한 대안 (0) | 2023.09.17 |
---|---|
MySQL varchar 인덱스 길이 (0) | 2023.09.17 |
CSS 플로트를 한 줄에 유지하려면 어떻게 해야 합니까? (0) | 2023.09.17 |
앵커 링크를 연결된 위치의 일부 픽셀 위로 이동합니다. (0) | 2023.09.17 |
WordPress 로그인 페이지 수정 문제 (0) | 2023.09.17 |