2013-05-24 4 views
1

나는 부모가있다.최대 절전 모드, @ManyToOne 삽입하고, EHCache는

이 같은 대략 간다 코드에서, 부모에 대한 업데이트를 처리 해요 :

  • 부모
    • 가에서 검색 받기 (순서대로 -으로 Ehcache, DB, 또는 발견되지 않는 경우는 작성)
  • 프로세스는 업데이트, 부모에 아이를 만드는 DB에
  • 저장을 찾을 수없는 경우
  • S 캐시에 찢어

를 통해 실행하면, 다음과 같은 순서

  • 첫 번째 업데이트가 완료 발생 찾을 - 부모에게 & 모두가 캐시
  • 두 번째 업데이트를 만든 아이 - 캐시에서 검색 부모를, 새를 아이는 두 번째 업데이트가 완료되면, 아이의 ID가 여전히 null의
    • 추가됩니다. 그러나 업데이트 을 성공적으로 완료했습니다. 다시 삽입되는 제 2 Update에서 아이로, DataIntegrityViolationException 발생합니다 -
  • 세 번째 업데이트 (최대 절전 로그 및 DB 모두에 대해 확인).

데이터베이스에서 반환되는 것이 아니라 부모가 캐싱된다는 사실과 관련이 있다고 가정합니다. 여기에 올바른 프로세스가 무엇인지 확신 할 수 없습니다.

관련 정보 : <

  • 학부모 -> 아이 다시 참조가 올바르게 정의 및 주석된다.
  • 부모의 초기 삽입 한 후, 나는 그것을하지 않았다 --- 그것은 차이를 만들어 있는지 확인하기 위해, 다시 가져오고 DB에서 부모를, 캐싱이 시도했습니다. 이 처음 @Transactional로 주석하고 내 테스트에서 실패하지 않았다으로
  • 트랜잭션 경계는 여기에 역할을해야합니다. (A 교훈은 하드 배웠)

무슨 이득이 처리하는 올바른 방법 - 아직도 가진 아이 엔티티가 제대로 추적하면서 특히, DB를마다의 부모를로드하는 것을 방지 할 수 있습니까?

코드의 예는 다음과 같습니다.

@Entity // Parent 
class Fixture { 

    @OneToMany(cascade=CascadeType.ALL, mappedBy="fixture", fetch=FetchType.EAGER) @Getter @Setter 
    @MapKey(name="instrumentPriceId") 
    private Map<String,Instrument> instruments = Maps.newHashMap(); 

    private Instrument addInstrument(Instrument instrument) 
    { 
     instruments.put(instrument.getInstrumentPriceId(), instrument); 
     instrument.setFixture(this); 
     log.info("Created instrument {}",instrument.getInstrumentPriceId()); 
     return instrument; 
    } 

    /** 
    * Returns an instrument with the matching instrumentId. 
    * If the instrument does not exist, it is created, appended to the internal collection, 
    * and then returned. 
    * 
    * This method is guaranteed to always return an instrument. 
    * This method is thread-safe. 
    * 
    * @param instrumentId 
    * @return 
    */ 
    public Instrument getInstrument(String instrumentId) 
    { 
     if (!instruments.containsKey(instrumentId)) 
     { 
      addInstrument(new Instrument(instrumentId)); 
     } 
     return instruments.get(instrumentId); 
    } 
} 

@Entity // Child 
public class Instrument { 

    @Column(unique=true) 
    @Getter @Setter 
    private String instrumentPriceId; 

    @ManyToOne(optional=false) 
    @Getter @Setter @JsonIgnore 
    private Fixture fixture; 

    public Instrument(String instrumentPriceId) 
    { 
     this.instrumentPriceId = instrumentPriceId; 
    } 
} 

그리고, 업데이트 프로세서 코드 :

class Processor { 
@Autowired 
@Qualifier("FixtureCache") 
private Ehcache fixtureCache; 

@Autowired 
private FixtureRepository fixtureRepository; 

void update(String fixtureId, String instrumentId) { 
    Fixture fixture = getFixture(fixtureId); 
    // Get the instrument, creating it & appending 
    // to the collection, if it doesn't exist 
    fixture.getInstrument(instrumentId); 

    // do some updates...ommitted 

    fixtureRepository.save(fixture); 

    fixtureCache.put(new Element(fixtureId, fixture));  
} 

/** 
* Returns a fixture. 
* Returns from the cache first, if present 
* If not present in the cache, the db is checked. 
* Finally, if the fixture does not exist, a new one is 
* created and returned 
*/ 
Fixture getFixture(String fixtureId) { 
    Fixture fixture; 
    Element element = fixtureCache.get(fixtureId); 
    if (element != null) 
    { 
     fixture = element.getValue(); 
    } else { 
     fixture = fixtureRepostiory.findOne(fixtureId); 
     if (fixture == null) 
     { 
      fixture = new Fixture(fixtureId); 
     } 
    } 
    return fixture; 
} 

}

답변

1

이에 대한 대답은 절망적 간단했다.

update 메서드에서 나는 save() 연산의 결과를 무시했습니다. 개체를 다시 사용할 계획이 없다면 종종 괜찮습니다. (이는 작업 단위의 끝에서 바로 저장함과 같이 일반적입니다). 나는 다시 내 '부모'를 계속 사용되면서

그러나, 나는 반환 값 관찰 할 필요 :

을 그래서이 :

fixture = fixtureRepository.save(fixture); 
fixtureCache.put(new Element(fixtureId, fixture));  
:

fixtureRepository.save(fixture); 
fixtureCache.put(new Element(fixtureId, fixture));  

이된다

관련 문제