Spring Data JPA和Hibernate的延迟加载异常

时间:2016-01-14 21:01:37

标签: java spring jpa

我正在尝试使用Hibernate学习Spring Data JPA,目前在Java独立项目中(虽然稍后我会在Web项目中使用内容),而我&#39 ;得到例外:

org.hibernate.LazyInitializationException:懒得初始化角色集合:com.dbprototype.domain.Crash.vehicles

我不确定原因。

@Entity(name = "STAGING.TEST_CRASH")
    public class Crash {

    @Id
    @Column(name = "C_TEST_CRASH_NUMBER")
    private int crashNum;

    @Column(name = "C_RECORD_NUMBER")
    private int recordNum;

    @Column(name = "C_TOTAL_UNITS")
    private int totalUnits;

    @Column(name = "C_TOTAL_INJURIES")
    private int totalInjured;

    @OneToMany(cascade=CascadeType.ALL, mappedBy="crash")  // fails.
    private List<Vehicle> vehicles; 

    @OneToOne(mappedBy="crash", cascade=CascadeType.ALL)   // this works ok.
    private Metadata metaData;

    public void printCrash() {
        // prints Crash fields, vehicles, and metadata.
    }

    // getters & setters
}


@Entity(name = "STAGING.TEST_VEHICLE")
public class Vehicle {
    @Id
    @Column(name = "V_TEST_VEHICLE_NUMBER")
    private int vehicleNum;

    //@Id
    @Column(name = "C_TEST_CRASH_NUMBER")
    private int crashNum;

    @Column(name = "C_RECORD_NUMBER")
    private int recordNum;

    @Column(name = "V_VEH_MAKE")
    private String vehicleMake;

    @Column(name = "V_VEH_MODEL")
    private String vehicleModel;

    @Column(name = "V_VEH_YEAR")
    private int year;

    @ManyToOne(cascade=CascadeType.ALL)
    private Crash crash;

    // getters & setters
}

我的服务层是:

@Service
@Transactional(propagation=Propagation.REQUIRED)
public class CrashService {

private CrashDao crashDao;

public void setCrashDao(CrashDao dao) {
    crashDao = dao;
}

public void print() {
    System.out.println("you called CrashService!");
}

// DAO layer will need all 4 CRUD operations on each table.

// read one Crash
public Crash readCrash(int id) {
    return crashDao.findOne(1000);
}

我的DAO层只是:

@Repository
public interface CrashDao extends CrudRepository<Crash, Integer>{ }

我的spring.xml是:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.2.xsd
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
    http://www.springframework.org/schema/data/jpa 
    http://www.springframework.org/schema/data/jpa/spring-jpa.xsd 
    ">

<!-- Scans the classpath for annotated components that will be auto-registered as Spring beans -->
<context:component-scan base-package="com.dbprototype" />

<!-- Activates various annotations to be detected in bean classes e.g: @Autowired -->
<context:annotation-config />

<jpa:repositories base-package="com.dbprototype.dao" />

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <!-- data source properties -->
</bean>

<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    <property name="generateDdl" value="false" />
    <property name="showSql" value="true" />
    <property name="databasePlatform" value="org.hibernate.dialect.OracleDialect" />
</bean> 

<bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />    
    <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
    <!-- Spring based scanning for @Entity classes -->
    <property name="packagesToScan" value="com.dbprototype.domain" />
</bean>  

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<tx:annotation-driven transaction-manager="transactionManager" />

</beans>

我不理解做@OneToMany的正确方法,虽然从一些教程中,我所拥有的是&#34;正确&#34;。虽然如果我改变@OneToMany使用EAGER加载而不是默认的LAZY,我会得到一个不同的例外:

org.springframework.dao.InvalidDataAccessResourceUsageException:无法提取ResultSet; SQL [不适用];嵌套异常是org.hibernate.exception.SQLGrammarException:无法提取ResultSet

引起:java.sql.SQLSyntaxErrorException:ORA-00904:&#34; VEHICLES1 _&#34;。&#34; CRASH_C_TEST_CRASH_NUMBER&#34;:无效标识符

有人可以帮助我了解正在发生的事情,以及如何正确地执行OneToMany吗?

由于 克里斯

1 个答案:

答案 0 :(得分:0)

这种关系是否适用于其他方式?如果您想从任何Crash访问Vechicle

Vechicle表格中的加入列是什么?我想,您错过了课程@JoinColumn中的Vechicle注释。

请参阅JPA WikiBook关于ManyToOnes:https://en.wikibooks.org/wiki/Java_Persistence/ManyToOne

代码:

@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name = "join_column_in_table_of_vechicle", reverseJoinColumn="C_TEST_CRASH_NUMBER")
private Crash crash;

如果没有,请提供表结构,并打开SQL-Logging,并提供select,这会导致异常。