2014-01-29 2 views
-2

Моего этот вопрос следить за вопросом JPA+one-to-many and many-to-one using join table or third tableJPA + много-к-одному целевые отношений объекта сохраняются в таблице

Я ссылающийся на Query в Response сущности. Когда я создаю запись для Response. Он также создает запись в таблице mydb.tbl_query. Мое требование состоит в том, что когда я вставляю объект Response, он должен вставить запись в mydb.tbl_response и создать запись в mydb.tbl_map_query_response путем ссылки query_id.

public class ResponseDAOImplTests extends BaseDAOImplTests { 

     @Autowired 
     @Qualifier("queryDAO") 
     private QueryDAO queryDAO; 

     @Autowired 
     @Qualifier("responseDAO") 
     private ResponseDAO responseDAO; 

     /** 
     * Query reference. 
     */ 
     private Query query = null; 

     /** 
     * <p> 
     * Adapter for earlier versions of JUnit. 
     * </p> 
     * 
     * @return a test suite. 
     */ 
     public static junit.framework.Test suite() { 
      return new JUnit4TestAdapter(ResponseDAOImplTests.class); 
     } 

     @Before 
     public void setUp() throws QADAOException { 
      user = accountDAO.getUser("[email protected]"); 
      query = queryDAO.getQuery(2); 

     } 

     @Test 
     public void createResponse() throws QADAOException { 
      Response response = new Response(); 
      response.setQuery(query); 
      response.setResponse("ResponseTest1"); 
      responseDAO.postResponse(response); 

     } 

    } 
public class ResponseDAOImpl extends BasePersitenceDAO implements ResponseDAO { 

    @Override 
    @Transactional 
    public void postResponse(Response response) throws QADAOException { 
     getEntityManager().persist(response); 
     getEntityManager().flush(); 

    } 
} 

public abstract class BasePersitenceDAO { 


    @PersistenceContext 
    private EntityManager entityManager; 
    protected BasePersitenceDAO() { 
     // Empty 
    } 
     protected EntityManager getEntityManager() { 
     return entityManager; 
    } 

     public void setEntityManager(EntityManager entityManager) { 
     this.entityManager = entityManager; 
    } 
} 

<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:tx="http://www.springframework.org/schema/tx" 
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:util="http://www.springframework.org/schema/util" 
    xsi:schemaLocation=" 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd 
     http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd 
     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> 
    <context:annotation-config /> 
    <tx:annotation-driven transaction-manager="transactionManager" /> 
    <context:component-scan base-package="com.qa" /> 
    <context:property-placeholder location="classpath:config.properties" /> 
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean"> 
     <property name="persistenceUnitName" value="persistenceUnit" /> 
    </bean> 
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
     <property name="entityManagerFactory" ref="entityManagerFactory" /> 
    </bean> 
    <bean id="basePersitenceDAO" abstract="true" class="com.qa.dao.impl.BasePersitenceDAOImpl" /> 
    <bean id="queryDAO" class="com.qa.dao.impl.QueryDAOImpl" parent="basePersitenceDAO" /> 
    <bean id="responseDAO" class="com.qa.dao.impl.ResponseDAOImpl" parent="basePersitenceDAO" /> 
</beans> 

Мой вопрос «не следует вводить еще одну запись в mydb.tbl_query».

+0

И ваш вопрос ...? –

+0

См. Последнюю строку. –

+0

В другом вопросе у Response есть много-к-одному для запроса с каскадом. Если вы сохраняете ответ, persist будет каскадироваться в объект Query, на который ссылается. То же самое происходит при слиянии и удалении вызовов. Он не должен вставлять новый объект Query в таблицу запросов, хотя, если он уже существует, возможно, вы создаете новый объект запроса. Вы должны найти существующую, если не хотите, чтобы новая запись была добавлена ​​в таблицу запросов. – Chris

ответ

1

Каскад заставляет каждую операцию JPA каскадировать над объектом, на который указывает ссылка. В этом случае, когда вы вызываете упор на новый объект Response, вы эффективно выполняете вызов на существующем отдельном объекте Query, который вы читали ранее и просто кэшировали локально. Он отсоединен, потому что раньше он был прочитан в другом контексте.

Если вы ищете спецификацию, то необходимо сохранить исключение, если вы вызываете его на отдельном объекте. Это просто не нужно делать сразу, а вместо этого позволяет вставить эту вставку, чтобы ваша база данных выдала ошибку - вы не упомянули об этом, но я предполагаю, что это то, что происходит. Чтобы этого избежать, вы не можете вызывать упор на отдельном объекте.

Вы можете легко исправить это несколькими способами 1), не используя каскад, сохраняйте свой ответ -> Отношение запросов. Cascade all включает каскадное сохранение, поэтому вам нужно добавить только каскадирование вашей модели. Я настоятельно рекомендую вам посмотреть, какие каскадные средства и использовать это в любом случае.
2) найдите запрос в том же контексте, в котором вы сохраняете ответ. Ваш ответ DAO может легко получить идентификатор запроса и строковое значение и создать для вас объект Response - выполнить поиск запроса с помощью Id.
3) вместо этого используйте слияние. Merge создаст новый ответ, но объединит отдельный экземпляр Query в управляемую копию, которую он ищет. Это может иметь риск, поскольку любые изменения, внесенные в объект Query, будут объединены и помещены в базу данных с помощью вставки Response. Таким образом, ваш ResponseDAO выбирает больше, чем просто изменения Response.

Смежные вопросы