2013-08-26 2 views
5

Я довольно новичок в Hibernate и пытаюсь определить, что он будет делать для вас и что он вам потребует.Hibernate, автоматически сохраняются зависимые объекты

Большой объект имеет дело с объектом, в котором есть иждивенцы, которых еще нет в базе данных. Например, у меня есть объект Project, который включает в себя поле «Производитель», которое принимает объект «Производитель» в качестве его значения. В базе данных у меня есть таблица продуктов с столбцом mfr_id, которая является ссылкой на таблицу производителей (довольно типичное однонаправленное отношение «один ко многим»).

Если производитель, присвоенный объекту продукта, относится к тому, который уже находится в базе данных, тогда нет проблем. Однако, когда я пытаюсь сохранить или обновить объект, который ссылается на производителя, который еще не был сохранен, операция завершается с исключением.

Исключение в потоке «Application» org.hibernate.TransientObjectException: объект ссылается на несохраненный переходный экземпляре - сохранить переходный экземпляр перед промывкой

Я могу конечно вручную проверить состояние производителя продукта по если это поле идентификатора равно null и сохраняет его, если оно есть, но это похоже на громоздкое решение. Поддерживает ли Hibernate автоматическое сохранение иждивенцев, если этот вопрос еще не сохраняется? Если да, как мне включить это поведение? Я использую версию Hibernate в комплекте с Netbeans (3.5, я считаю) и встроенные аннотации для указания поведения отображения. Ниже приведены классы моего продукта и производителя, которые вырезали на части, которые обрабатывают зависимость. (Расширяет продукт Продаваемая, который отображает на продаваемую таблицу, используя JOINED как стратегия наследования Это та таблица, которая содержит первичный ключ, который идентифицирует продукт)

@Entity 
@Table (
     name="products", 
     schema="sellable" 
) 
public abstract class Product extends Sellable { 
    private Manufacturer      manufacturer; 

    @ManyToOne (fetch = FetchType.EAGER) 
    @JoinColumn (name = "mfr_id") 
    public Manufacturer getManufacturer() { 
     return this.manufacturer; 
    } 

    /** 
    * 
    * @param manufacturer 
    */ 
    public Product setManufacturer (Manufacturer manufacturer) { 
     this.manufacturer = manufacturer; 
     return this; 
    } 
} 

Зависимая Производитель

@Entity 
@Table (
     name="manufacturers", 
     schema="sellable", 
     uniqueConstraints = @UniqueConstraint(columnNames="mfr_name") 
) 
public class Manufacturer implements Serializable { 
    private Integer   mfrId  = null; 
    private String   mfrName  = null; 

    @Id 
    @SequenceGenerator (name = "manufacturers_mfr_id_seq", sequenceName = "sellable.manufacturers_mfr_id_seq", allocationSize = 1) 
    @GeneratedValue (strategy = GenerationType.SEQUENCE, generator = "manufacturers_mfr_id_seq") 
    @Column (name="mfr_id", unique=true, nullable=false) 
    public Integer getMfrId() { 
     return mfrId; 
    } 

    private Manufacturer setMfrId (Integer mfrId) { 
     this.mfrId = mfrId; 
     return this; 
    } 

    @Column(name="mfr_name", unique=true, nullable=false, length=127) 
    public String getMfrName() { 
     return mfrName; 
    } 

    public Manufacturer setMfrName (String mfrName) { 
     this.mfrName = mfrName; 
     return this; 
    } 
} 

UPDATE: Я попробовал следующее с this question, но я все еще получаю исключение переходного объекта.

@ManyToOne (fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE}) 

Я также проверил, какая версия Hibernate поставляется с Netbeans, это 3.2.5

UPDATE 2: Я обнаружил, что следующее, кажется, по-видимому, работать, как я хотел.

@ManyToOne (fetch = FetchType.EAGER, cascade = CascadeType.ALL) 

Однако, я подозреваю, что это не каскадный тип, который я действительно хочу. Если я удалю продукт, я не думаю, что удаление его ассоциированного производителя - это правильное действие, которое, как я полагаю, произойдет сейчас.

Я попытался создать каскадный тип, состоящий из всех доступных типов, но это тоже не сработало. У меня такое же исключение, когда я пытался сохранить продукт, у которого был несохраненный производитель, связанный с ним.

@ManyToOne (fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}) 

Я видел CascadeType.SAVE_UPDATE упоминается в нескольких местах, но этот режим, кажется, не будет доступна в версии Hibernate, которая поставляется с Netbeans.

ответ

7

Вы должны посмотреть на каскадные операции; этот тип операции позволяет вам управлять жизненным циклом внутреннего объекта в отношении своего родителя.

@ManyToOne(cascade) если вы используете Session.persist() операцию или [email protected], если вы используете не JPA функцию Session.saveOrUpdate().

Это просто пример, для полной точки док here

Для вашего кода, если вы хотите, чтобы автоматически сохранить Manufacturer при сохранении Project использования:

@ManyToOne (fetch = FetchType.EAGER, cascade = {javax.persistence.CascadeType.PERSIST}) 
@JoinColumn (name = "mfr_id") 
public Manufacturer getManufacturer() { 
    return this.manufacturer; 
} 

или

@Cascade(CascadeType.PERSIST) 
+0

Я попробовал ваше предложение, но при попытке сохранить объект все равно получаю такое же исключение в отношении временных объектов. Я также попробовал подход, предложенный в http://stackoverflow.com/questions/9032998/hibernate-cascades-object-references-an-unsaved-transient-instance-save- of \t @ManyToOne (fetch = FetchType.EAGER, каскад = {CascadeType.PERSIST, CascadeType.MERGE}), но это не сработало ни – GordonM

+0

, вы используете saveOrUpdate()? в этом случае вам нужно 'org.hibernate.annotation. @ Cascade (CascadeType.SAVE_UPDATE)' –

+0

На данный момент я просто использую save(). Я посмотрю другие варианты, когда вернусь домой сегодня вечером. – GordonM

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