有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java延迟加载异常与Spring数据JPA和Hibernate

我正在尝试使用Hibernate学习Spring Data JPA,目前在一个Java独立项目中(尽管稍后我将在一个Web项目中使用),我得到了一个例外:

组织。冬眠LazyInitializationException:未能延迟初始化role:com的集合。dbprototype。领域崩溃车辆

我不知道为什么

@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>{ }

我的春天。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的正确方法,尽管从一些教程中,我得到的是“正确的”。不过,如果我将@OneToMany更改为使用渴望加载而不是默认的懒惰加载,我会得到一个不同的例外:

组织。springframework。刀。InvalidDataAccessResourceUsageException:无法提取结果集;SQL[n/a];嵌套的异常是org。冬眠例外SQLGrammarException:无法提取结果集

原因:java。sql。SQLSyntaxErrorException:ORA-00904:“车辆1”。“CRASH_C_TEST_CRASH_NUMBER”:无效标识符

有人能帮我理解发生了什么事,以及如何正确地完成“OneToMany”吗

谢谢 克里斯


共 (1) 个答案

  1. # 1 楼答案

    这种关系是以另一种方式运作的吗?如果您想从任何Vechicle访问Crash

    Vechicle的表中,join列是什么?我想,你错过了类@JoinColumn中的Vechicle注释

    请参阅JPA维基百科中关于多通的内容: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日志记录,并提供导致异常的select