JPA存储库中的双向关联不起作用

时间:2013-04-21 17:36:10

标签: java spring hibernate java-ee jpa

以下是我的表格:

ORDER

CREATE TABLE ORDER_DETAILS (
       ID INT NOT NULL AUTO_INCREMENT
     , ORDER_ID VARCHAR(60) NOT NULL
     , ADDRESS_ID  INT 
--     , DRIVER_ID  INT 
     , BARCODE_ID  INT
     , CUSTOMER_ID  VARCHAR(60) 
     , CUSTOMER_PIN  VARCHAR(60) 
     , UNIQUE UQ_ORDER_ID_1 (ORDER_ID)
, FOREIGN KEY(BARCODE_ID) REFERENCES public.BARCODE(ID)
     , PRIMARY KEY (ID)
);

AND BARCODE

CREATE TABLE BARCODE (
   ID INT NOT NULL AUTO_INCREMENT
 , BARCODE_DETAILS VARCHAR(60) NOT NULL
 , DRIVER_ID  INT 
 , VERSION INT NOT NULL DEFAULT 0
 , UNIQUE UQ_BARCODE_ID_1 (BARCODE_DETAILS)
 , PRIMARY KEY (ID));

订购条形码是多对一关系,即许多订单可以有一个条形码

这是我的存储库

OrderRepository

package com.eppvd.application.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import com.eppvd.application.domain.Address;
import com.eppvd.application.domain.Customer;
import com.eppvd.application.domain.Driver;
import com.eppvd.application.domain.Order;

public interface OrderRepository extends JpaRepository<Order, Long> {

    Order findByOrderId(String orderId);
//  Order findByBarcode(String barcode);
    Order findByCustomerPin(String customerPin);

//  Order findByDriver(Driver driver);
    Order findByAddress(Address address);
    Order findByCustomer(Customer customer);

}

BarcodeRepository

package com.eppvd.application.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.eppvd.application.domain.Barcode;


public interface BarcodeRepository extends JpaRepository<Barcode, Long> {

    Barcode findByBarcode(String barcode);
}

这是我的ServiceImpls

OrderServiceImpl

package com.eppvd.application.service.jpa;
/** imports **/

@Service("OrderService")
@Repository
@Transactional
public class OrderServiceImpl implements OrderService {

    /** Other Methods **/

    @Override
    @Transactional(propagation=Propagation.REQUIRED, readOnly=false)
    public Order save(Order order) {
        return orderRepository.save(order);
    }

    @Override
    public void flush(){
        orderRepository.flush();
    }

}

BarcodeServiceImpl

package com.eppvd.application.service.jpa;
@Service(value="barcodeService")
@Repository
@Transactional
public class BarcodeServiceImpl implements BarcodeService{

    @Autowired
    BarcodeRepository barcodeRepository;
    @Override
    @Transactional(propagation=Propagation.REQUIRED,readOnly=false)
    public Barcode save(Barcode barcode) {

        return barcodeRepository.save(barcode);
    }

}

和实体

package com.eppvd.application.domain;
@Entity
@Table(name = "order_details")
public class Order implements Serializable {
    private Barcode barcode;

    @ManyToOne(optional = false)
    @JoinColumn(name="BARCODE_ID")
    public Barcode getBarcode() {
        return barcode;
    }   
    public void setBarcode(Barcode barcode) {
        this.barcode = barcode;
    }
}

package com.eppvd.application.domain;


@Entity
@Table(name = "barcode")
public class Barcode implements Serializable {


private static final long serialVersionUID = 3202943305655732979L;
private Long id;
private int version;
private String barcode_details;
private Set<Order> orders ;

@Column(name="BARCODE_DETAILS")
public String getBarcodeDetails() {
    return barcodeDetails;
}

public void setBarcodeDetails(String barcode) {
    this.barcodeDetails = barcode;
}

@OneToMany(cascade=CascadeType.ALL,mappedBy="barcode",fetch=FetchType.EAGER)
public Set<Order> getOrders() {
    return orders;
}

public void setOrders(Set<Order> orders) {
    this.orders = orders;
}

}

和应用程序上下文

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

    <jdbc:embedded-database id="dataSource" type="H2">
        <jdbc:script location="classpath:schema.sql"/>
<!--         <jdbc:script location="classpath:test-data.sql"/>     -->
    </jdbc:embedded-database>

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

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

    <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
        </property>        
        <property name="packagesToScan" value="com.eppvd.application.domain"/>
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
                <prop key="hibernate.max_fetch_depth">3</prop>
                <prop key="hibernate.jdbc.fetch_size">50</prop>
                <prop key="hibernate.jdbc.batch_size">10</prop>
                <prop key="hibernate.show_sql">true</prop> 
                <prop key="hibernate.hbm2ddl.auto">create</prop>             
            </props>        
        </property>
    </bean>    

    <context:annotation-config/>    

    <jpa:repositories base-package="com.eppvd.application.repository"
                      entity-manager-factory-ref="emf"
                      transaction-manager-ref="transactionManager"/>  

<!--      <bean id="customerService" class="com.eppvd.application.service.jpa.CustomerServiceImpl"> -->
<!--  </bean>   -->
    <context:component-scan base-package="com.eppvd.application.service.jpa"></context:component-scan>

</beans>

和JUNit测试

package com.eppvd.application.service;

import static org.junit.Assert.*;
@ContextConfiguration(locations="classpath:datasource-tx-jpa.xml")
@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
public class OrderServiceTest {

    @Autowired
    private OrderService orderService;

    @Autowired
    private BarcodeService barcodeService;

    @Before
    public void createAddressCustomerDriver(){

        Barcode barcode = new Barcode();
        barcode.setBarcodeDetails("1234");
        barcodeService.save(barcode);
    }

    @Test
    public void testCreateOrder() {
        Barcode barcode = barcodeService.findByBarcode("1234");

        Order order = new Order();
        order.setOrderId("OD001");
        order.setBarcode(barcode);
        order.setCustomerPin("1234");
        order.setCustomer(customerService.findByFirstName("Abhijit"));
        order.setAddress(addressService.findByStreet("BTM Layout"));



        orderService.save(order);
        orderService.flush();
        Set<Order> orders = barcode.getOrders();
assertEquals("1234", orderService.findByOrderId("OD001").getBarcode().getBarcodeDetails()); /**Works **/
        assertEquals(1, orders.size()); /**FAILS **/

    }
}

我试着尽可能详细。所以它变得有点长。任何帮助将不胜感激。我试图从逻辑上弄清楚一切,但不太确定我错过了什么。这方面的文档很少

1 个答案:

答案 0 :(得分:0)

您创建了一个订单,并初始化了其条形码。但您从未将订单添加到条形码的订单集中。所以它的条形码是空的。这是预期的。

如果你期望它们是连贯的,你应该保持一个协会的双方。