简体   繁体   中英

Bidirectional Association In JPA Repository Not Working

Here are my tables:

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));

Order to Barcode is Many To One Relationship ie Many Order Can Have One barcode

Here Are My repositories

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);

}

And 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);
}

Here Are My 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();
    }

}

And 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);
    }

}

And Entities

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;
}

}

and application Context

<?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>

And JUNit Test

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 **/

    }
}

I tried To be as detailed as possible. So it became a bit long. Any help would be greatly appreciated. I tried to figure out everything logically but not too sure what am I missing.There is little documentation around this area

You created an Order, and initialized its barcode. But you never added the order to the set of orders of the barcode. So its set of barcodes is empty. That's expected.

You're supposed to maintain the two sides of an association if you expect them to be coherent.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM