Я довольно новичок в Hibernate и использовал онлайн-форумы &, но я в тупике по этой проблеме. Я использую Spring 3.2 с Hibernate 4 & Аннотации. У меня есть родительская (PledgeForm) таблица & child (PledgeFormGiftLevel), которая является «один ко многим».OneToMany Create Fails с InvalidDataAccessApiUsageException
Домен/Модели: Родитель
@Entity
@Table(name="PLEDGE_FORMS")
@SuppressWarnings("serial")
public class PledgeForm implements Serializable {
static final Logger log = Logger.getLogger(PledgeForm.class);
@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="pledge_form_seq")
@SequenceGenerator(name="pledge_form_seq", sequenceName="PLEDGE_FORM_SEQ")
@Column(name="ID", unique=true, nullable=false)
private Integer id;
….
@OneToMany(mappedBy="pledgeForm", fetch=FetchType.EAGER, cascade=CascadeType.ALL)//********1
private List<PledgeFormGiftLevel> pledgeFormGiftLevels = new ArrayList<PledgeFormGiftLevel>();
….
public List<PledgeFormGiftLevel> getPledgeFormGiftLevels() {
return this.pledgeFormGiftLevels;
}
public void setPledgeFormGiftLevels(List<PledgeFormGiftLevel> pledgeFormGiftLevels) {
this.pledgeFormGiftLevels = pledgeFormGiftLevels;
}
//I do not think the following method is needed, but I decided to try it just in case
public void addPledgeFormGiftLevels(PledgeFormGiftLevel pledgeFormGiftLevels) {
pledgeFormGiftLevels.setPledgeForm(this);
getPledgeFormGiftLevels().add(pledgeFormGiftLevels);
}
Детский
@Entity
@Table(name="PLEDGE_FORM_GIFT_LEVELS")
@SequenceGenerator(name="pledge_form_gift_level_seq", sequenceName="PLEDGE_FORM_GIFT_LEVEL_SEQ")
@SuppressWarnings("serial")
public class PledgeFormGiftLevel implements Serializable {
static final Logger log = Logger.getLogger(PledgeFormGiftLevel.class);
@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="pledge_form_gift_level_seq")
@Column(name="ID", unique=true, nullable=false)
private Integer id;
…
@ManyToOne(fetch=FetchType.EAGER)//yes?
@JoinColumn(name="PLEDGE_FORM_ID", referencedColumnName="ID", insertable=true, updatable=true)//yes?
private PledgeForm pledgeForm = new PledgeForm();
…
public PledgeForm getPledgeForm() {
return pledgeForm;
}
public void setPledgeForm(PledgeForm pledgeForm) {
this.pledgeForm = pledgeForm;
}
Controller (есть графика, поэтому у меня есть код, чтобы тянуть в файле):
@Controller
@SessionAttributes("pledgeForm")
public class PledgeFormController {
@Autowired
org.unctv.service.PledgeFormManager Service;
…
@RequestMapping(value = "/saveJdbcPledgeForm", method = RequestMethod.POST, params="save")
public ModelAndView save(
@ModelAttribute("pledgeForm")
@Valid PledgeForm pledgeForm, BindingResult result,
@RequestParam("logoImg") MultipartFile file,
@RequestParam(value="removeLogoImg", required=false) String removeLogoImg) throws Exception {
ModelAndView mav = null;
mav = new ModelAndView("pledgeFormSearch");//Name of the JSP
if (removeLogoImg != null) {
pledgeForm.setLogoFilename(null);
pledgeForm.setLogoImg(null);
pledgeForm.setLogoContentType(null);
} else if (file != null && file.getBytes().length > 0) {
pledgeForm.setLogoFilename(file.getOriginalFilename());
pledgeForm.setLogoImg(file.getBytes());
pledgeForm.setLogoContentType(file.getContentType());
}
Service.save(pledgeForm);
mav.addObject("pledgeForm", pledgeForm);//JSP Form's Command Name (pledgeForm);
mav.addObject("cmdName", "pledgeForm");
mav.addObject("actionType", "Save");
return mav;
}
Услуги:
@Service("simplePledgeFormManager")
@Transactional(readOnly=true)
public class SimplePledgeFormManager implements PledgeFormManager {
@Autowired
private HibernatePledgeFormDao hibernatePledgeFormDao;
…
@Transactional(readOnly=false)
public void save(PledgeForm pledgeForm) throws Exception {
hibernatePledgeFormDao.save(pledgeForm);
}
DAO:
@Repository("PledgeFormDAO")
public class HibernatePledgeFormDao implements PledgeFormDao {
static final Logger log = Logger.getLogger(HibernatePledgeFormDao.class);
@Autowired
private SessionFactory sessionFactory;
...
@Override
public void save(PledgeForm pledgeForm) throws Exception {
sessionFactory.getCurrentSession().saveOrUpdate(pledgeForm);
}
Используя код выше, родитель/дочерние записи могут быть выбраны и обновляются в порядке. Когда я показываю «след» сообщения из спящего режима, обновление имеет этот след сообщение о ребенке, хотя:
[2013-12-06 10:31:24,648] TRACE Persistent instance of: org.unctv.domainmodel.PledgeFormGiftLevel
[2013-12-06 10:31:24,649] TRACE Ignoring persistent instance
[2013-12-06 10:31:24,649] TRACE Object already associated with session: [org.unctv.domainmodel.PledgeFormGiftLevel#1]
создать всегда дает эту ошибку, если есть ребенок запись:
object references an unsaved transient instance - save the transient instance before flushing: org.unctv.domainmodel.PledgeForm; nested exception is org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: org.unctv.domainmodel.PledgeForm
Когда я смотрю журналы спящего режима, я вижу, что он обновляет родительский элемент & на основе переходных объектов. Затем он пытается сбросить & находит постоянную копию ребенка, поэтому он откатывает все.
[2013-12-06 10:34:13,615] TRACE Automatically flushing session
[2013-12-06 10:34:13,615] TRACE Flushing session
[2013-12-06 10:34:13,615] DEBUG Processing flush-time cascades
[2013-12-06 10:34:13,615] TRACE Processing cascade ACTION_SAVE_UPDATE for: org.unctv.domainmodel.PledgeForm
[2013-12-06 10:34:13,615] TRACE Cascade ACTION_SAVE_UPDATE for collection: org.unctv.domainmodel.PledgeForm.pledgeFormGiftLevels
[2013-12-06 10:34:13,615] TRACE Cascading to save or update: org.unctv.domainmodel.PledgeFormGiftLevel
[2013-12-06 10:34:13,616] TRACE Persistent instance of: org.unctv.domainmodel.PledgeFormGiftLevel
[2013-12-06 10:34:13,616] TRACE Ignoring persistent instance
[2013-12-06 10:34:13,616] TRACE Object already associated with session: [org.unctv.domainmodel.PledgeFormGiftLevel#51]
[2013-12-06 10:34:13,616] TRACE Done cascade ACTION_SAVE_UPDATE for collection: org.unctv.domainmodel.PledgeForm.pledgeFormGiftLevels
[2013-12-06 10:34:13,616] TRACE Done processing cascade ACTION_SAVE_UPDATE for: org.unctv.domainmodel.PledgeForm
[2013-12-06 10:34:13,617] DEBUG Dirty checking collections
[2013-12-06 10:34:13,617] TRACE Flushing entities and processing referenced collections
[2013-12-06 10:34:13,617] DEBUG Collection found: [org.unctv.domainmodel.PledgeForm.pledgeFormGiftLevels#51], was: [<unreferenced>] (initialized)
[2013-12-06 10:34:13,618] DEBUG rolling back
[2013-12-06 10:34:13,618] DEBUG rolled JDBC Connection
Документация Hibernate это показывает, как даже проще, чем я мой код, но я должен был добавить выборки & значения каскадного. Я играл с изменением каскадных значений & & (начиная с документации Hibernate &, а затем добавляя), но все остальное, что я пытаюсь сделать, все же вызывает сбой создания. & часто приводит к сбою обновления.
Многие сообщения в форуме, которые я нахожу, показывают flush() или evict(). Я не уверен, что это Hibernate 4 или аннотации (@Transactional, я думаю), я использую, но я не вижу места для этого в своем коде. Из журналов трассировки Hibernate я вижу, что промывка происходит автоматически с помощью метода saveOrUpdate().
Я также попытался сбросить таблицы & последовательностей & начиная свежими.
Приветствуется любой совет о создании работы на работу. Если вы можете указать мне на определенную документацию, которую я пропустил, это тоже оценено.
Спасибо, Бонни
Только быстрое примечание. Имена переменных Java строчные. Поэтому 'org.unctv.service.PledgeFormManager Service;' должно быть 'org.unctv.service.PledgeFormManager service;' Если бы существовал фактический класс 'Service' со статическими методами, которые могли бы вызвать проблемы. Я подозреваю, что именно поэтому вы используете полное имя. Есть ли еще один класс «Сервис»? –
Возвращает ли «PledgeForm» из пользовательского интерфейса с набором «PledgeFormGiftLevel»? –
@KevinBowersox, спасибо за советы. Я использовал этот учебник при изучении Весны - http://javabeginnerstutorial.com/spring-framework-tutorial/developing-a-spring-3-framework-mvc-application-step-by-step-tutorial/ - и Я получил от Службы Капитала. Я на самом деле предположил, что это особая весенняя вещь, которая должна быть капитализирована. Я могу внести это изменение. В моем проекте нет статического класса, называемого «Сервис». –