내가 저장하기 전에 복잡한 객체 그래프의 스냅 샷을 가정하고 프로젝트의 비슷한 요구 사항을 가지고 필요한 것입니다. 난 적용한
용액 1)의 오브젝트의 복제를 작성하여 동일한 테이블에 삽입 hiberante 깊은 클론 업체 유틸리티 쓸
2 setArchiveFlag
)는 오리지널, 무시 무효화 같은 특정 속성 정의 주석 @Archivable을 개발 하였다. deep cloner는 간단한 트릭을 검색하고 객체를 deslite 처리하여 새 인스턴스를 만든 다음 id 및 version을 null로 설정합니다.
3) 엔티티 인터셉터에서 아카이브 날씨를 결정하기 위해 cloner 유틸리티를 사용했습니다.
아래 코드 중 일부입니다.
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
public @interface Archivable {
/** This will mark property as null in clone */
public String[] nullify() default {};
/**
* If property is archivable but not from enclosing entity then specify as
* ignore.
*/
public String[] ignore() default {};
/**
* sets original reference to clone for back refer data. This annotation is
* applicable to only root entity from where archiving started.
*
* @return
*/
public String original() default "";
/**
* if marks cloned entity to archived, assumes flag to be "isArchived".
* @return
*/
public boolean setArchiveFlag() default false;
}
@Component
public class ClonerUtils {
private static final String IS_ARCHIVED = "isArchived";
@Autowired
private SessionFactory sessionFactory;
public Object copyAndSave(Serializable obj) throws Exception {
List<BaseEntity> entities = new ArrayList<BaseEntity>();
Object clone=this.copy(obj,entities);
this.save(clone, entities);
return clone;
}
public Object copy(Serializable obj,List<BaseEntity> entities) throws Exception{
recursiveInitliaze(obj);
Object clone = SerializationHelper.clone(obj);
prepareHibernateObject(clone, entities);
if(!getOriginal(obj).equals("")){
PropertyUtils.setSimpleProperty(clone, getOriginal(obj), obj);
}
return clone;
}
private void save(Object obj,List<BaseEntity> entities){
for (BaseEntity baseEntity : entities) {
sessionFactory.getCurrentSession().save(baseEntity);
}
}
@SuppressWarnings("unchecked")
public void recursiveInitliaze(Object obj) throws Exception {
if (!isArchivable(obj)) {
return;
}
if(!Hibernate.isInitialized(obj))
Hibernate.initialize(obj);
PropertyDescriptor[] properties = PropertyUtils.getPropertyDescriptors(obj);
for (PropertyDescriptor propertyDescriptor : properties) {
Object origProp = PropertyUtils.getProperty(obj, propertyDescriptor.getName());
if (origProp != null && isArchivable(origProp) && !isIgnore(propertyDescriptor, obj)) {
this.recursiveInitliaze(origProp);
}
if (origProp instanceof Collection && origProp != null) {
for (Object item : (Collection) origProp) {
this.recursiveInitliaze(item);
}
}
}
}
@SuppressWarnings("unchecked")
private void prepareHibernateObject(Object obj, List entities) throws Exception {
if (!isArchivable(obj)) {
return;
}
if (obj instanceof BaseEntity) {
((BaseEntity) obj).setId(null);
((BaseEntity) obj).setVersion(null);
if(hasArchiveFlag(obj)){
PropertyUtils.setSimpleProperty(obj, IS_ARCHIVED, true);
}
entities.add(obj);
}
String[] nullifyList = getNullifyList(obj);
for (String prop : nullifyList) {
PropertyUtils.setProperty(obj, prop, null);
}
PropertyDescriptor[] properties = PropertyUtils.getPropertyDescriptors(obj);
for (PropertyDescriptor propertyDescriptor : properties) {
if (isIgnore(propertyDescriptor, obj)) {
continue;
}
Object origProp = PropertyUtils.getProperty(obj, propertyDescriptor.getName());
if (origProp != null && isArchivable(origProp)) {
this.prepareHibernateObject(origProp, entities);
}
/** This code is for element collection */
if(origProp instanceof PersistentBag){
Collection elemColl=createNewCollection(origProp);
PersistentBag pColl=(PersistentBag) origProp;
elemColl.addAll(pColl.subList(0, pColl.size()));
PropertyUtils.setSimpleProperty(obj, propertyDescriptor.getName(), elemColl);
continue;
}
if (origProp instanceof Collection && origProp != null) {
Collection newCollection = createNewCollection(origProp);
PropertyUtils.setSimpleProperty(obj, propertyDescriptor.getName(), newCollection);
for (Object item : (Collection) origProp) {
this.prepareHibernateObject(item, entities);
}
}
}
}
@SuppressWarnings("unchecked")
private Collection createNewCollection(Object origProp) {
try {
if(List.class.isAssignableFrom(origProp.getClass()))
return new ArrayList((Collection)origProp);
else if(Set.class.isAssignableFrom(origProp.getClass()))
return new HashSet((Collection)origProp);
else{
Collection tempColl=(Collection) BeanUtils.cloneBean(origProp);
tempColl.clear();
return tempColl;
}
} catch (Exception e) {
e.printStackTrace();
}
return new ArrayList();
}
private boolean isIgnore(PropertyDescriptor propertyDescriptor,Object obj){
String propertyName=propertyDescriptor.getName();
String[] ignores=getIgnoreValue(obj);
return ArrayUtils.contains(ignores, propertyName);
}
private String[] getIgnoreValue(Object obj) {
String[] ignore=obj.getClass().getAnnotation(Archivable.class).ignore();
return ignore==null?new String[]{}:ignore;
}
private String[] getNullifyList(Object obj) {
String[] nullify=obj.getClass().getAnnotation(Archivable.class).nullify();
return nullify==null?new String[]{}:nullify;
}
public boolean isArchivable(Object obj) {
return obj.getClass().isAnnotationPresent(Archivable.class);
}
private String getOriginal(Object obj) {
String original=obj.getClass().getAnnotation(Archivable.class).original();
return original==null?"":original;
}
private boolean hasArchiveFlag(Object obj) {
return obj.getClass().getAnnotation(Archivable.class).setArchiveFlag();
}
@SuppressWarnings({ "unchecked", "unused" })
private Collection getElemColl(Object obj, Object origProp) {
Collection elemColl=createNewCollection(origProp);
for (Object object : (Collection)origProp) {
elemColl.add(object);
}
return elemColl;
}
@SuppressWarnings("unused")
private boolean isElementCollection(Object obj, String name) {
try {
Annotation[] annotations=obj.getClass().getDeclaredField(name).getAnnotations();
for (Annotation annotation : annotations) {
if(annotation.annotationType() == ElementCollection.class)
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
최대 절전 모드를 이미 사용중인 경우 여기를 클릭하면 도움이 될 수 있습니다. –
매우 좋음! 나는이 사실을 몰랐다. 감사! – pabhb