Spring+Hibernate + OneToMany<->ManyToOne bidirectional relationship
От: andreyzz  
Дата: 24.10.13 18:25
Оценка:
Здравствуйте уважаемые форумчане.

В hibernate orm я новичок, потому запутался в 3х соснах. гугль особо не помог,видимо не те вопросы ему задаю.
потому расчитываю на помощь живых людей.
итак ситуация
вот куски кода( набирал руками, чтобы отразить основные моменты, которые я не понимаю)

 public class Parent  {
 ...
 @Access(value = AccessType.PROPERTY)
  @ElementCollection(targetClass = ParentData.class)
  @Cascade({org.hibernate.annotations.CascadeType.ALL})
  @OneToMany(mappedBy = "parent",/*cascade = CascadeType.ALL,*/ fetch = FetchType.EAGER, orphanRemoval = true)
  private Set<ParentData> parentDataList;
  
  @Transient
  private Actual3rdPartyParentDataHolder dataHolder;
  
  ...
  Set<ParentData> getParentDataList() {
    
    for (ParentData c : dataHolder.getData()) {
      parentDataList.add(ParentData.createData(this, c));
    }
    return parentDataList;
  }
  public void setAccountCookieList(Set<ParentData> parentDataList) {
    assert this.parentDataList != null;
    this.parentDataList.addAll(parentDataList);
    dataHolder.addAll(parentDataList)
  }
  }
  
  class PArentData imlements IData {
    ....
    тут Simple java types  (int, string,boolean etc)
    
  }
  class Actual3rdPartyParentDataHolder {
    public IData getData() {
        return врутренняя реализация этого интерфейса, представленная 3rd party developer.
    }
  }
  
  public class ParentData implements IData {
     
     ...
     @ManyToOne(fetch = FetchType.EAGER) // вот тут у меня есть сомнения, м.б. надо LAZY?
    @Cascade({org.hibernate.annotations.CascadeType.ALL})
    @JoinColumn(name = "parent_id")
     private Parent parent; //геттер и сеттер обычные автогенереные, без изысков
     
     public static ParentData createData(Parent parent,IData data) {
        setParent(parent).
        ...
        //копируем данные из data в свои поля
     }
     }


@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = {"off.register.persistence"}, excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, value = Configuration.class))
public class PersistenceConfiguration {

  @Autowired
  @Qualifier("sessionFactory")
  private SessionFactory sessionFactory;

  @Bean
  public PlatformTransactionManager transactionManager() {
    return new HibernateTransactionManager(sessionFactory);
  }

  @Bean
  public HibernateExceptionTranslator hibernateExceptionTranslator() {
    return new HibernateExceptionTranslator();
  }

  @Configuration
  @Profile("dev")
  @PropertySource("classpath:persistence.properties")
  static class Develop {
    @Bean
    @Qualifier("sessionFactory")
    public LocalSessionFactoryBean sessionFactory(Environment environment) {
      String packageOfModelBeans = Account.class.getPackage().getName();

      LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();

      factoryBean.setDataSource(dataSource());
      factoryBean.setHibernateProperties(buildHibernateProperties(environment));
      factoryBean.setPackagesToScan(packageOfModelBeans);
      return factoryBean;
    }

    @Bean
    public DataSource dataSource() {
      return new EmbeddedDatabaseBuilder()
              .setType(EmbeddedDatabaseType.HSQL)
                      //.addScript("classpath:com/bank/config/sql/schema.sql")
                      //.addScript("classpath:com/bank/config/sql/test-data.sql")
              .build();
    }

    /**
     * Loading all the hibernate properties from a properties file
     */
    protected Properties buildHibernateProperties(Environment env) {
      Properties hibernateProperties = new Properties();

      hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
      hibernateProperties.setProperty("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
      hibernateProperties.setProperty("hibernate.use_sql_comments", env.getProperty("hibernate.use_sql_comments"));
      hibernateProperties.setProperty("hibernate.format_sql", env.getProperty("hibernate.format_sql"));
      hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));

      hibernateProperties.setProperty("hibernate.generate_statistics", env.getProperty("hibernate.generate_statistics"));

      hibernateProperties.setProperty("javax.persistence.validation.mode", env.getProperty("javax.persistence.validation.mode"));

      //Audit History flags
      hibernateProperties.setProperty("org.hibernate.envers.store_data_at_delete", env.getProperty("org.hibernate.envers.store_data_at_delete"));
      hibernateProperties.setProperty("org.hibernate.envers.global_with_modified_flag", env.getProperty("org.hibernate.envers.global_with_modified_flag"));

      return hibernateProperties;
    }


  }

}




interface ParentDao {
  Parent find(Integer Id);
}

@Repository
public class ParentDaoImpl {

  @Autowired
  ServiceFactory sf;
  public Parent find(Integer id) {
    return (Parent) sf.getCurrentSession().get(Parent.class,id);
  }
}

interface ParentService {
 Parent find(Integer Id);
}
@Service
public class PArentServiceImpl {
  @Autowired
  ParentDao dao;
  public Parent find(Integer id) {
   return dao.find(id);
  }
  
}


теперь я пытаюсь все это завести.
делаю тест

@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("dev")
@ContextConfiguration(
        loader = AnnotationConfigContextLoader.class,
        classes = {
                PersistenceCOnfiguration.class
        })
@Transactional
public class ParentTest {

@Autowired
  ParentService parentService;
  private  Parent p ;
  @Before
  public void setup() {
      p = new Parent();
      p.getDataHolder().populateWithData(...)// вообщем заполняем поля которые Set<? extends IData>
      parentService.save(p);
      assertNotNull(p.getId()); // будет null, если не сохранился
  }
  
  @Test 
  public void test_can_find() {
      Parent p2 =  parentService.find(p.getId());
      assertNotSame(p2,p);
  }
}


и вот тут в test_can_find у меня начинаются танцы с бубном ибо
assertNotSame(p2,p) — неверно, ну это я и так знаю ибо ParentTest объявлен как @Transactional

если я убираю @Transactional — тест падает на NullPointerException в Parent#setParentDataList() при поптыке прочитать значение

насколько я понял, проблема заключается в том, что hibernate в качестве значений для parentDataList в классе PArent подсовывает свои прокси классы, которые в свою очередь имеют lazy-initialization полей класса ParentData ( почему? у меня ведь в @OneToMany и @ManyToOne объявлены оба как FetchType.EAGER)

внимание вопрос
как на выходе своего parentService получить цельный экзепляр Parent с востановленным dataHolder внутри него
при этом, чтобы можно было обращаться к этому экземпляру вне методов, объявленных как @Transactional и повторные запросы parentService.find(id) возвращали мне не один и тот же (прокси-)класс ( или экземпляр PArent который ссылается на (прокси?)класс для Set<ParentData>)?
т.е. я хочу при загрузке из parentService экземпляра
Parent прозрачно проинициализировать некоторые значения поля @Transient
private Actual3rdPartyParentDataHolder dataHolder;
и получить этот Parent никоим образом более не относящийся к hibernate, т.е. хочу свой POJO назад
читал что-то про interface UserType и interface CompositeUserType — ничего не понял и отложил это на потом — оно мне подойдет или токо время в моем случае зря потрачу?

и правильно ли я понимаю, что аннотация @Transactional эквивалентна следующему псевдо-коду:
@Transactional public void method();
=
beginTransaction();
boolean r=false;
try {
 method();
 r=true;
catch(Exception) {
} finally {
 if (r)
  commit();
 else 
   rollback()
}



целый день убил на поиски решения, все что я смог придумать это для parentDAO методов типа save, findById
добавить что-то типа

public void save(Parent p) {
  p.copyDataFrom3rdPartyToParentDataSet()
  serviceFactory().getCurrentSession().save(p);
}
public PArent load(Integer id) {
  Parent p = (Parent )serviceFactory().getCurrentSession().load(Parent.class,id);    
  p.copyDataFRomParentDataSetTo3rdPartyDataHolder();
}

и соотв-но сделать обычные геттер\сеттер методы для Parent#parentDataList, не забыв при этом поменять аннотацию
@Access(value = AccessType.PROPERTY) на @Access(value = AccessType.FIELD)
для
Set<ParentData> parentDataList в классе PArent

но это пока токо в теории, на практике не проверял

была мысль о том, чтобы метод find в parentService сделать без @Transactional аннотации , а самому открывать и закрывать сессию
но в этом случае у меня вылетает ошибка в тесте на parentService.find(id)
failed to lazily initialize — no session or session was closed — гугль подсказывает, что дело в FetchType.LAZY для OneToMany/ManyToOne
но у меня-то там изначально стоит EAGER

вообщем я запутался в конец.

помогите с этой кашей разобраться пжлст ))
Re: Spring+Hibernate + OneToMany<->ManyToOne bidirectional relationship
От: GreenTea  
Дата: 25.10.13 09:37
Оценка:
Здравствуйте, andreyzz, Вы писали:

A>Здравствуйте уважаемые форумчане.


A>В hibernate orm я новичок, потому запутался в 3х соснах. гугль особо не помог,видимо не те вопросы ему задаю.

A>потому расчитываю на помощь живых людей.
A>итак ситуация
A>вот куски кода( набирал руками, чтобы отразить основные моменты, которые я не понимаю)

A>
...
A> @Access(value = AccessType.PROPERTY)
A>  @ElementCollection(targetClass = ParentData.class)
A>  @Cascade({org.hibernate.annotations.CascadeType.ALL})
A>  @OneToMany(mappedBy = "parent",/*cascade = CascadeType.ALL,*/ fetch = FetchType.EAGER, orphanRemoval = true)
A>  private Set<ParentData> parentDataList;
  
A>  @Transient
A>  private Actual3rdPartyParentDataHolder dataHolder;
  
A>  ...
A>  Set<ParentData> getParentDataList() {
    
A>    for (ParentData c : dataHolder.getData()) {
A>      parentDataList.add(ParentData.createData(this, c));
A>    }
A>    return parentDataList;
..
A>


Тут не понял, вы пытаетесь сохранить parentDataList, и в то же время в геттере сущности какая то логика, по вытаскиванию списка извне.
Дам вам совет, никакой логики в сущностях модели. Обычный гет и сет. Иначе намучаетесь с хибернетом, даже если на первый взгляд покажется что проблемм нет.

A>[/java]


A>теперь я пытаюсь все это завести.

A>делаю тест

A>
A>@RunWith(SpringJUnit4ClassRunner.class)
A>@ActiveProfiles("dev")
A>@ContextConfiguration(
A>        loader = AnnotationConfigContextLoader.class,
A>        classes = {
A>                PersistenceCOnfiguration.class
A>        })
A>@Transactional
A>public class ParentTest {
...
A>


Поставте аннотацию @Transactional на реализации сервиса с propagation=REQUIRED, а так же на реализации дао с propagation=MANDATORY. Так при вызове сервиса будет создана новая транзакция если ее не было, а на дао она же подхватится, или будет кинуто исключение если транзакции нет (чтобы нельзя было вызывать дао не из веб сервисов). На юнит тесте вообще не уверн нужна ли она.

Это первые очевидные ошибки которые бросились в глаза. Возможно что-то еще есть.
Re[2]: Spring+Hibernate + OneToMany<->ManyToOne bidirectional relationship
От: andreyzz  
Дата: 25.10.13 20:05
Оценка:
GT>Тут не понял, вы пытаетесь сохранить parentDataList, и в то же время в геттере сущности какая то логика, по вытаскиванию списка извне.
GT>Дам вам совет, никакой логики в сущностях модели. Обычный гет и сет. Иначе намучаетесь с хибернетом, даже если на первый взгляд покажется что проблемм нет.
тут как раз все нормально ( не зря же я целый день гугл и форумы буржуинские читал) при условии, тчо геттер\сеттер акромя как hibernate никем не используется ( в моем случае я их package local сделал для этого) в моем нормальном коде я такие интересные моменты ссылками с объяснениями комментирую, если там шибко много и умно расписывают. тут банально — если есть логика, то сам не трогай! иначе будет dirty entity

GT>Поставте аннотацию @Transactional на реализации сервиса с propagation=REQUIRED, а так же на реализации дао с propagation=MANDATORY. Так при вызове сервиса будет создана новая транзакция если ее не было, а на дао она же подхватится, или будет кинуто исключение если транзакции нет (чтобы нельзя было вызывать дао не из веб сервисов). На юнит тесте вообще не уверн нужна ли она.


у меня нет веб-сервисов. вообще. спринг это еще и java SE все-таки.
транзакции как раз создаются нормально, я же хочу получать not-managed-by-hibernate-entity на выходе сервиса. покурил еще документацию, похоже что это невозможно, если не делать deep copy объектов явно.
для моих целей это не критично, потому оставляю как есть.

на юнит-тестах транзакции нужны, просто у каждого теста будет сделан rollback по его окончании ( это дефолтное поведение тестов для работы с орм) т..е все будет ок.

все-равно спасибо за ответы )
Re[3]: Spring+Hibernate + OneToMany<->ManyToOne bidirectional relationship
От: GreenTea  
Дата: 25.10.13 21:09
Оценка:
Здравствуйте, andreyzz, Вы писали:

GT>>Тут не понял, вы пытаетесь сохранить parentDataList, и в то же время в геттере сущности какая то логика, по вытаскиванию списка извне.

GT>>Дам вам совет, никакой логики в сущностях модели. Обычный гет и сет. Иначе намучаетесь с хибернетом, даже если на первый взгляд покажется что проблемм нет.
A>тут как раз все нормально ( не зря же я целый день гугл и форумы буржуинские читал) при условии, тчо геттер\сеттер акромя как hibernate никем не используется ( в моем случае я их package local сделал для этого) в моем нормальном коде я такие интересные моменты ссылками с объяснениями комментирую, если там шибко много и умно расписывают. тут банально — если есть логика, то сам не трогай! иначе будет dirty entity

Не понял объяснения.. Хибренет работает в обход этого геттера напрямую с полем? Если нет — то будут проблемы.

A>как на выходе своего parentService получить цельный экзепляр Parent с востановленным dataHolder внутри него ...

public void setAccountCookieList(Set<ParentData> parentDataList) {
    assert this.parentDataList != null;
    this.parentDataList.addAll(parentDataList);
    dataHolder.addAll(parentDataList)
  }

А кто будет вызывать этот сеттер?
Может все таки должно быть setParentDataList? Хотя судя по логике внутри — нет.. Вообще каша какая-то. Я этот код не понимаю
Можете описать требования словами без кода? Т.к. у меня подозрение что вы все реализовали.. кхм, не совсем правильно с архитектурной точки зрения.

GT>>Поставте аннотацию @Transactional на реализации сервиса с propagation=REQUIRED, а так же на реализации дао с propagation=MANDATORY. Так при вызове сервиса будет создана новая транзакция если ее не было, а на дао она же подхватится, или будет кинуто исключение если транзакции нет (чтобы нельзя было вызывать дао не из веб сервисов). На юнит тесте вообще не уверн нужна ли она.


A>у меня нет веб-сервисов. вообще. спринг это еще и java SE все-таки.

A> транзакции как раз создаются нормально, я же хочу получать not-managed-by-hibernate-entity на выходе сервиса. покурил еще документацию, похоже что это невозможно, если не делать deep copy объектов явно.
A>для моих целей это не критично, потому оставляю как есть.

А я и не говорил про веб сервиса.

@Service
public class PArentServiceImpl {

Это обычный сервис. Транзакция есть только на момент вызова к примеру sf.getCurrentSession().get(Parent.class,id); о после возвращения результата ее уже не будет. А должна обрамлять весь вызов к сервису, т.к. если внутри сервиса, посреди бизнес операции вылетит эксепшен, а вы до этого поменяли данные, то первоначальные изменения будут сохранены — что не есть правильно. + если после возврата сущности надо будет подгрузить ленивых чайлдов, то без активной транзакции это не удастся.

A>на юнит-тестах транзакции нужны, просто у каждого теста будет сделан rollback по его окончании ( это дефолтное поведение тестов для работы с орм) т..е все будет ок.


A>все-равно спасибо за ответы )


Кстати, дурной тон писать трансляцию в статическом методе.
public static ParentData createData(Parent parent,IData data) {
        setParent(parent).
        ...
        //копируем данные из data в свои поля
     }

Используйте для этого транслятор (некоторые называют ассемблер), — объект который конвертирует IData в ParentData и если надо — наоборот.
Re[4]: Spring+Hibernate + OneToMany<->ManyToOne bidirectional relationship
От: andreyzz  
Дата: 25.10.13 21:49
Оценка:
Здравствуйте, GreenTea, Вы писали:

GT>Здравствуйте, andreyzz, Вы писали:


GT>>>Тут не понял, вы пытаетесь сохранить parentDataList, и в то же время в геттере сущности какая то логика, по вытаскиванию списка извне.

GT>>>Дам вам совет, никакой логики в сущностях модели. Обычный гет и сет. Иначе намучаетесь с хибернетом, даже если на первый взгляд покажется что проблемм нет.
A>>тут как раз все нормально ( не зря же я целый день гугл и форумы буржуинские читал) при условии, тчо геттер\сеттер акромя как hibernate никем не используется ( в моем случае я их package local сделал для этого) в моем нормальном коде я такие интересные моменты ссылками с объяснениями комментирую, если там шибко много и умно расписывают. тут банально — если есть логика, то сам не трогай! иначе будет dirty entity

GT>Не понял объяснения.. Хибренет работает в обход этого геттера напрямую с полем? Если нет — то будут проблемы.


A>>как на выходе своего parentService получить цельный экзепляр Parent с востановленным dataHolder внутри него ...

GT>
GT>public void setAccountCookieList(Set<ParentData> parentDataList) {
да тут опечатка setParentDataList  - соотв-но при @Access(value = AccessType.PROPERTY) доступ к полю будет фактически приводить к вызову геттера\сеттера, т.е. само поле по сути не нужно мне.
GT>    assert this.parentDataList != null;
GT>    this.parentDataList.addAll(parentDataList);
GT>    dataHolder.addAll(parentDataList)
GT>  }
GT>

GT>А кто будет вызывать этот сеттер?
GT>Может все таки должно быть setParentDataList? Хотя судя по логике внутри — нет.. Вообще каша какая-то. Я этот код не понимаю
GT>Можете описать требования словами без кода? Т.к. у меня подозрение что вы все реализовали.. кхм, не совсем правильно с архитектурной точки зрения.
попробую описать в целом.
есть система управления "водопровод". в ней есть датчики, эти датчики необходимо периодически регистироравать в системе\ удалять оттуда. обрабатывать данные, и пересылать обработанные данные 3му лицу.
сразу оговорюсь, что эта система уже имеет реализацию на perl но в 21веке это уже некошерно и .т.к. я являюсь ее разработчиком, то решено было двинуть в 21 с явой наперевес.
регистрация и удаление датчиков в системе — это рилтайм процесс, который не требует каких-то действий со стороны persistance. нообработка данных — процесс неспешный и ресурсозатратный, потому для нормальной работы будет использоваться ферма ПК, и данные соотв-но будут храниться в БД.
входные данные от датчиков — это (с тточки зрения явы) набор 3rd party классов, поля которых( не все, но важные для обработки) я пытаюсь сохранять в БД, чтобы в будущем, по команде оператора, можно было их восстановить.
обработка данных проводится (в реализации на перл -многопроцессно) многопоточно. соотв-но я незнаю, как в java SE поведут себя hibernate persistence entitites в многопоточном режиме (я никогда этого не реализовывал еще и не дебажил. потому стараюсь подстелить себе сразу подстилку, чтобы не больно падать было)
вообщем-то потому и хочу этот пресловутый persistance layer использовать ровно настолько, насколько я его понимаю. т.е. положить\взять данные и более об этом persistence layer не вспоминать.



GT>>>Поставте аннотацию @Transactional на реализации сервиса с propagation=REQUIRED, а так же на реализации дао с propagation=MANDATORY. Так при вызове сервиса будет создана новая транзакция если ее не было, а на дао она же подхватится, или будет кинуто исключение если транзакции нет (чтобы нельзя было вызывать дао не из веб сервисов). На юнит тесте вообще не уверн нужна ли она.


A>>у меня нет веб-сервисов. вообще. спринг это еще и java SE все-таки.

A>> транзакции как раз создаются нормально, я же хочу получать not-managed-by-hibernate-entity на выходе сервиса. покурил еще документацию, похоже что это невозможно, если не делать deep copy объектов явно.
A>>для моих целей это не критично, потому оставляю как есть.

GT>А я и не говорил про веб сервиса.


GT>
GT>@Service
GT>public class PArentServiceImpl {
GT>

GT>Это обычный сервис. Транзакция есть только на момент вызова к примеру sf.getCurrentSession().get(Parent.class,id); о после возвращения результата ее уже не будет. А должна обрамлять весь вызов к сервису, т.к. если внутри сервиса, посреди бизнес операции вылетит эксепшен, а вы до этого поменяли данные, то первоначальные изменения будут сохранены — что не есть правильно. + если после возврата сущности надо будет подгрузить ленивых чайлдов, то без активной транзакции это не удастся.

A>>на юнит-тестах транзакции нужны, просто у каждого теста будет сделан rollback по его окончании ( это дефолтное поведение тестов для работы с орм) т..е все будет ок.


A>>все-равно спасибо за ответы )


GT>Кстати, дурной тон писать трансляцию в статическом методе.

GT>
GT>public static ParentData createData(Parent parent,IData data) {
GT>        setParent(parent).
GT>        ...
GT>        //копируем данные из data в свои поля
GT>     }
GT>

GT>Используйте для этого транслятор (некоторые называют ассемблер), — объект который конвертирует IData в ParentData и если надо — наоборот.
спасибо за совет, а есть ли смысл большойй (кроме красоты кода, которыф кроме меня никто не увидит)?
следование стандартным подходам хорошо, када есть время, а когда надо "вчера" о таких "мелочах" вспоминается в лучшем случае, после Nого рефакторинга
у меня, к сожалению, подход именно такой, что надо чтобы тест отрабатывал. а как там это все реализовано — не суть. дешевле железок наставить будет если что( не судите строго — я тоже человек и по 25часов в сутки не могу код писать)
Re[5]: Spring+Hibernate + OneToMany<->ManyToOne bidirectional relationship
От: andreyzz  
Дата: 25.10.13 21:51
Оценка:
Здравствуйте, andreyzz, Вы писали:


GT>>
GT>>@Service
GT>>public class PArentServiceImpl {
GT>>

GT>>Это обычный сервис. Транзакция есть только на момент вызова к примеру sf.getCurrentSession().get(Parent.class,id); о после возвращения результата ее уже не будет. А должна обрамлять весь вызов к сервису, т.к. если внутри сервиса, посреди бизнес операции вылетит эксепшен, а вы до этого поменяли данные, то первоначальные изменения будут сохранены — что не есть правильно. + если после возврата сущности надо будет подгрузить ленивых чайлдов, то без активной транзакции это не удастся.

это да уже на тестах понял сегодня сей момент. потому и написал выше, что смирюсь с @Transactional методами, где требуются работа с данными изи persistence entities. не суть критично
Re[5]: Spring+Hibernate + OneToMany<->ManyToOne bidirectional relationship
От: GreenTea  
Дата: 26.10.13 08:59
Оценка:
A>попробую описать в целом.
A>есть система управления "водопровод". в ней есть датчики, эти датчики необходимо периодически регистироравать в системе\ удалять оттуда. обрабатывать данные, и пересылать обработанные данные 3му лицу.
A>сразу оговорюсь, что эта система уже имеет реализацию на perl но в 21веке это уже некошерно и .т.к. я являюсь ее разработчиком, то решено было двинуть в 21 с явой наперевес.
A>регистрация и удаление датчиков в системе — это рилтайм процесс, который не требует каких-то действий со стороны persistance. нообработка данных — процесс неспешный и ресурсозатратный, потому для нормальной работы будет использоваться ферма ПК, и данные соотв-но будут храниться в БД.
A>входные данные от датчиков — это (с тточки зрения явы) набор 3rd party классов, поля которых( не все, но важные для обработки) я пытаюсь сохранять в БД, чтобы в будущем, по команде оператора, можно было их восстановить.
A>обработка данных проводится (в реализации на перл -многопроцессно) многопоточно. соотв-но я незнаю, как в java SE поведут себя hibernate persistence entitites в многопоточном режиме (я никогда этого не реализовывал еще и не дебажил. потому стараюсь подстелить себе сразу подстилку, чтобы не больно падать было)
A>вообщем-то потому и хочу этот пресловутый persistance layer использовать ровно настолько, насколько я его понимаю. т.е. положить\взять данные и более об этом persistence layer не вспоминать.

Если сейчас задача просто положить данные которые возвращают датчики, то напрашивается такая структура.
Делаете шедулер (например qartz) который с заданной периодичностью опрашивает датчики, на слое сервисов эти данные транслируются в persistence сущности и сохраняются. Вся бизнес логика должна быть на слое сервисов, а на персистенсе голые персистентные сущности без какой либо логики и транзиентных dataHolder-ов. Если ваша многопоточная обработка данных не будет их модифицировать, то проблем быть не должно — вытаскиваете потом сохраненные данные и обрабатываете.
Re[6]: Spring+Hibernate + OneToMany<->ManyToOne bidirectional relationship
От: andreyzz  
Дата: 26.10.13 09:21
Оценка:
Здравствуйте, GreenTea, Вы писали:

GT>Если сейчас задача просто положить данные которые возвращают датчики, то напрашивается такая структура.

GT>Делаете шедулер (например qartz) который с заданной периодичностью опрашивает датчики, на слое сервисов эти данные транслируются в persistence сущности и сохраняются. Вся бизнес логика должна быть на слое сервисов, а на персистенсе голые персистентные сущности без какой либо логики и транзиентных dataHolder-ов. Если ваша многопоточная обработка данных не будет их модифицировать, то проблем быть не должно — вытаскиваете потом сохраненные данные и обрабатываете.

да вообщем-то так примерно все архитектурно и спланировано, мой вопрос изначально был про то, как мне уйти от @Transaction при получении ссущностей из БД ))
если у Parent класса нет @OneToMany полей, то все, на первый взгляд, взлетает вне @transaction методов, при этом я понимаю, что модификация данных в Parent классе внутри этих методов может привести к dirty entity со всеми вытекающими, но изменений вносить в класс никто не будет, потому считаю что мое решение оправдано.
в случае с @OneToMany полем начинается какая-то мутная свистопляска с LAZY полями — почему у меня не подхватывается fetchType.EAGER я, честно, не понял еще.
потому, чтобы тесты не рушились мне приходится все логику работы связанную с экземплярами Parent, полученными из БД оборачивать в @Transaction.


по поводу голых сущностей — буду иметь ввиду, спасибо за совет, но все-таки @Access(FIELD/PROPERTY) , мне кажется , придумали не просто так.
interface UserType я так понимаю это тоже "какая-то логика", и она тоже имеет место быть для полей в наших persistent entity.
как бы то ни было в тестах ничего не падает следовательно считаю, что работает. если нет — сделаю +1 тест под ошибку и будем его "закрывать".
как-то так ))

спасибо еще раз за советы.
Re[5]: Spring+Hibernate + OneToMany<->ManyToOne bidirectional relationship
От: tavr  
Дата: 28.10.13 13:18
Оценка:
Здравствуйте, andreyzz, Вы писали:

A>попробую описать в целом.

A>есть система управления "водопровод". в ней есть датчики, эти датчики необходимо периодически регистироравать в системе\ удалять оттуда. обрабатывать данные, и пересылать обработанные данные 3му лицу.
A>сразу оговорюсь, что эта система уже имеет реализацию на perl но в 21веке это уже некошерно и .т.к. я являюсь ее разработчиком, то решено было двинуть в 21 с явой наперевес.
perl рулит
A>регистрация и удаление датчиков в системе — это рилтайм процесс, который не требует каких-то действий со стороны persistance. нообработка данных — процесс неспешный и ресурсозатратный, потому для нормальной работы будет использоваться ферма ПК, и данные соотв-но будут храниться в БД.
A>входные данные от датчиков — это (с тточки зрения явы) набор 3rd party классов, поля которых( не все, но важные для обработки) я пытаюсь сохранять в БД, чтобы в будущем, по команде оператора, можно было их восстановить.
A>обработка данных проводится (в реализации на перл -многопроцессно) многопоточно. соотв-но я незнаю, как в java SE поведут себя hibernate persistence entitites в многопоточном режиме (я никогда этого не реализовывал еще и не дебажил. потому стараюсь подстелить себе сразу подстилку, чтобы не больно падать было)
A>вообщем-то потому и хочу этот пресловутый persistance layer использовать ровно настолько, насколько я его понимаю. т.е. положить\взять данные и более об этом persistence layer не вспоминать.
Я но знаю полного набора требований, но исходя из вышеописанного, я бы отказался от вложенных объектов вообще и Hibernate в частности.
Данные для обработки в базе можно представить в виде view или плоской временной таблицы.
Вообще предпочтительней делать вычисления на стороне базы, а не вытягивать данные для обработки, чтобы потом просто сложить по каким-то критериям...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.