1

Я довольно новичок в 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().

Я также попытался сбросить таблицы & последовательностей & начиная свежими.

Приветствуется любой совет о создании работы на работу. Если вы можете указать мне на определенную документацию, которую я пропустил, это тоже оценено.

Спасибо, Бонни

+0

Только быстрое примечание. Имена переменных Java строчные. Поэтому 'org.unctv.service.PledgeFormManager Service;' должно быть 'org.unctv.service.PledgeFormManager service;' Если бы существовал фактический класс 'Service' со статическими методами, которые могли бы вызвать проблемы. Я подозреваю, что именно поэтому вы используете полное имя. Есть ли еще один класс «Сервис»? –

+0

Возвращает ли «PledgeForm» из пользовательского интерфейса с набором «PledgeFormGiftLevel»? –

+0

@KevinBowersox, спасибо за советы. Я использовал этот учебник при изучении Весны - http://javabeginnerstutorial.com/spring-framework-tutorial/developing-a-spring-3-framework-mvc-application-step-by-step-tutorial/ - и Я получил от Службы Капитала. Я на самом деле предположил, что это особая весенняя вещь, которая должна быть капитализирована. Я могу внести это изменение. В моем проекте нет статического класса, называемого «Сервис». –

ответ

0

Я заметил, что equals и hashcode не были переопределены в субъектах. Эти методы используются для сравнения объектов для определения их равенства. Hibernate не может определить, существует ли существующий экземпляр объекта без переопределения этих методов. Попробуйте обеспечить реализацию для hashcode и equals.

Если вы используете Eclipse, нажмите CTRL + SHIFT + S, H, чтобы вызвать диалоговое окно для создания hashcode и equals методы. Выберите поля, которые содержат значения, которые относительно не изменяются, а затем генерируют методы.

быть также уверены, что вы управляете с обеих сторон лица, как описано выше в комментариях:

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 

     //Manage both sides of the entity 
     List<PledgeFormGiftLevel> levels = pledgeForm.getPledgeFormGiftLevels(); 

     for(PledgeFormGiftLevel level: levels){ 
      level.setPledgeForm(pledgeForm); 
     } 

     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; 
} 
+0

Код «Управление обеими сторонами», который вы указали выше, заработал. Огромное спасибо. Я чувствовал, что мне нужно явно установить дочерние значения в массиве родителя, но я не знал, где их получить. Мне никогда не приходило в голову вытащить их из самого родителя. Я все еще работаю над выяснением hashcode и равно, но я продолжу и соглашусь с вашим ответом. Я очень ценю очень ясную помощь, а также другие советы, которые вы предлагали. –

+0

@BonnieSmyre Отлично! Я полагаю, что методы хеш-кода и равенства будут использоваться при выполнении обновления объекта. Был ли ваш текущий случай вставкой? –

+0

На самом деле, обновление уже работало и продолжает работать. Это была проблема с вставкой. –

Смежные вопросы