문제

UPDATE: EXAMPLE TO CLARIFY I'm going to put an example of what's happening just to clarify the situation in my Spring + Hibernate application. Imagine I have this two entities (suppose getters and setters exists too)

@Entity
public class Class1(){
  private Integer id;

  @OneToOne
  private Class2 object2;
}

@Entity
public class Class2(){
  private Integer id;

  @OneToOne
  private Class1 object2;
}

So in my database I have two tables to map every instance of each object. Suppose I have stored in the database these objects:

  • objectA (class Class1) : id = 1 , object2 = objectB
  • objectB (class Class2) : id = 2 , object2 = objectA
  • objectC (class Class2) : id = 3 , object2 = null which means A anb B are linked. Suppose now I want to link objectA to objectC. It means I have to delete the link in the objectB too.

For doing this I do the folowing:

//I get the objectA from database
Class1 storedObjectA = myservice.find(objectAId);
//Now in storedObject1 I have the same as what it is stored as objectA

//I change only the object2 attribute of it
storedObject1.setObject2(objectC);

//I search again in the database to see objectA
Class1 reStoredObjectA = myservice.find(objectAId);

restoredObjectA now is:

  • restoredObjectA (class = Class1) id = 1, object2 = objectC

though in the database there is:

  • restoredObjectA (class = Class1) id = 1, object2 = objectB

The method find has not searched in the database and I have gotten the previous search though I have my query and second level caches disabled. The method find only goes to the DAO where it executes on the entityManager.find(Class1.class, id) How can I make my second find searchs in the database?

Thanks


(Full explanation)

Hello,

I have an application which uses Spring 3 and Hibernate. I have an entity named Class1 which is stored in a database. This entity has a OneToOne link to another entity called Class2. Class2 has another OneToOne Link to Class1, and both links have unique property set to true.

I have the following code in my controller:

//I have an object called dataFromUser which is instance of Class1 and
// it is obtained via @ModelAttribute annotation from a form

Integer id = dataFromUser.getId();

//I get correctly the stored object from the database
Class1 storedData = myService.find(id); //this will call em.find of hibernate

//I set to the stored data the attribute I want to change
storedData.setObject2();

//I save again the object
myService.save(storedData);

The method save in myService will use the entity manager to persist the data, but before that it will check the previous association between Class1 object and Class2 object to delete it in case a new Class2 Object has set to the instance of Class1. For that reason I have to call find method again to see what's in my database

In the Service:

@Transactional
public void save(Class1 object1){
   Class1 objectFromDB =  myDAO.find(object1.getId());
   // ....  update the old object and save
}

The problem is that objectFromDB in the Service is not the same as when I did myService.find(id) in the controller. The problem is that it is not looking for it in the database but it is searching in memory. I know it because there is no SQL statement logged when the second find() method is called. As I had done setObject2() on the storedData object I get exactly this object when I call find method for the second time, and the database doesn't contain this because it hasn't been persisted yet.

I have tried to disable Cache in my configuration just to try, but it is still happening. I have a ehCache with this configuration:

In persistence.xml I have this properties (I have set to false both caches):

    <properties>
     <!-- Hibernate 3.5.0 - try org.hibernate.cache.* package -->
  <property name="hibernate.cache.provider_class"
               value="net.sf.ehcache.hibernate.SingletonEhCacheProvider" />
   <property name="hibernate.cache.use_query_cache" value="false" />
  <property name="hibernate.cache.use_second_level_cache" value="false" />
  <property name="hibernate.generate_statistics" value="true" />
  <property name="hibernate.cache.use_structured_entries" value="false" />
  <property name="hibernate.format_sql" value="true" />
  <!-- http://www.jroller.com/eyallupu/entry/hibernate_s_hbm2ddl_tool -->
  <!-- create, create-drop, update, validate -->
  <property name="hibernate.hbm2ddl.auto" value="update" />
    </properties>  

In my ehcache.xml I have set to 0 maxElementsInMemory and overflowToDisk to false to disable it too.

Is there any way to avoid this situation?

Thanks.

도움이 되었습니까?

해결책 2

OK, I find it out. The problem is that hibernate looks for the objects in its Session before searching in the database. so I had to detached the object to the session before modifying it. To do so in hibernate:

    //being em my EntityManager instance
    Session session = (Session) em.getDelegate();
    session.evict(plan); 
    //Now the find object will not get the object wich is in session 
    //but the one in database

다른 팁

SharePoint 2010의 경우 웹 앱에 SharePoint 사이트와 다른 도메인이있는 경우이 오류가 발생합니다.

이면 iframe 또는 JSONP를 사용하여 매우 해킹 솔루션없이 가능하지 않습니다.

나쁜 소식의 무기명이되어서 죄송합니다. 서버 액세스가 필요합니다. CORS는 교차 도메인 공격으로부터 사람들을 보호하기 위해 서버 액세스가 필요합니다. IIS에서 수행하는 방법에 대한 링크가 있습니다 (호스트 SharePoint)

SharePoint Enviornment에 액세스 할 수있는 경우 SharePoint 내에서이를 호스팅하는 것이 훨씬 쉬워 질 수 있습니다. IIS 서버의 디렉토리를 만들고 웹 응용 프로그램 파일을 배포 할 수도 있습니다. 그렇게하면 동일한 도메인을 가질 수 있습니다.

자체 서버에 배포 해야하는 경우 SharePoint를 호출하는 자체 API를 개발해야합니다. 이 API는 .NET SharePoint CSOM을 사용할 수 있도록 .NET에서 가장 잘 구축 될 것입니다.

SharePoint 2013을 사용하면 SharePoint Apps를 살펴 보겠습니다. 외부 시스템에서 응용 프로그램을 작성할 수 있으며 사람들은 SharePoint 에 설치할 수 있습니다.

편집 : SharePoint 2013 앱 모델과 Microsoft가 제공 한 교차 도메인 라이브러리에서는 확실히 가능합니다. 전체 데모를 위해이 비디오를보십시오. 무엇이 필요할 것인가?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top