hibernate annotation one-to-many
От: -Sergey- Украина  
Дата: 12.03.08 13:12
Оценка:
привет всем.
проблема в следующем: создается новый объект, у которого есть отношение один ко многим к другому классу, в данный Лист добавляются новые экземпляры при сохранении базового класса происходит ексепшин, ругается на отсуствие foreignkey — нов базеон есть, скорее всего напутал где-то с аннотациями но самому найти не удалось ..

@Entity
@Table( name = "Bill" )
public class Bill
{
    private long billId;
    private Set<Payment> payments = new HashSet<Payment>();

    public Bill()
    {
    }

    @Id
    @GeneratedValue( strategy = GenerationType.AUTO )
    public long getBillId()
    {
        return billId;
    }

    @OneToMany( fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "paymentId")
    public Set<Payment> getPayments()
    {
        return payments;
    }
}


@Entity
@Table( name = "Payment" )
public class Payment
{
    private long paymentId;
    private String name;
    private Bill bill;


    public Payment()
    {
    }


    @Id
    @GeneratedValue( strategy = GenerationType.AUTO )
    public long getPaymentId()
    {
        return paymentId;
    }

    @ManyToOne( fetch = FetchType.LAZY )
    @JoinColumn( name = "billId" )
    public Bill getBill()
    {
        return bill;
    }

}


эксепшен

12.3.2008 03:00:51 - [logger: org.hibernate.tool.hbm2ddl.SchemaExport ] INFO:  Running hbm2ddl schema export
12.3.2008 03:00:51 - [logger: org.hibernate.tool.hbm2ddl.SchemaExport ] INFO:  exporting generated schema to database
12.3.2008 03:00:51 - [logger: org.hibernate.tool.hbm2ddl.SchemaExport ] INFO:  schema export complete
Hibernate: select gen_id( hibernate_sequence, 1 ) from RDB$DATABASE
Hibernate: select gen_id( hibernate_sequence, 1 ) from RDB$DATABASE
Hibernate: select gen_id( hibernate_sequence, 1 ) from RDB$DATABASE
Hibernate: insert into Bill (billId) values (?)
Hibernate: insert into Payment (name, billId, paymentId) values (?, ?, ?)
12.3.2008 03:00:52 - [logger: org.hibernate.util.JDBCExceptionReporter ] WARN:  SQL Error: 335544466, SQLState: HY000
12.3.2008 03:00:52 - [logger: org.hibernate.util.JDBCExceptionReporter ] ERROR:  GDS Exception. 335544466. violation of FOREIGN KEY constraint "FK3454C9E6497E4391" on table "PAYMENT"
Foreign key reference target does not exist
12.3.2008 03:00:52 - [logger: org.hibernate.event.def.AbstractFlushingEventListener ] ERROR:  Could not synchronize database state with session
org.hibernate.exception.GenericJDBCException: could not insert: [com.common.model.sub.Payment]
    at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2263)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2656)
    at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:52)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
    at org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:388)
    at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:363)
    at org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:676)
    at com.common.dao.impl.BillDaoImpl.saveBill(BillDaoImpl.java:17)
    at com.common.run.MainUnit.main(MainUnit.java:80)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
Caused by: org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544466. violation of FOREIGN KEY constraint "FK3454C9E6497E4391" on table "PAYMENT"
Foreign key reference target does not exist
    at org.firebirdsql.jdbc.AbstractPreparedStatement.internalExecute(AbstractPreparedStatement.java:711)
    at org.firebirdsql.jdbc.AbstractPreparedStatement.executeUpdate(AbstractPreparedStatement.java:171)
    at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:23)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2243)
    ... 18 more


сам код который вызывает исключение


       Bill bill = new Bill();

        Payment payments = new Payment();
        payments.setName( "fruits" );

        Payment payment2 = new Payment();
        payment2.setName( "goods" );

        bill.getPayments().add( payment2 );
        bill.getPayments().add( payments );

        IBillDAO billDAO = ( IBillDAO ) applicationContext.getBean( "billDao" );
        billDAO.saveBill( bill );
-
[color="gray"]
Цель в жизни определяет все..
Выбор есть всегда..
Но мы часто не хотим его делать..
[/color]
Re: hibernate annotation one-to-many
От: Blazkowicz Россия  
Дата: 12.03.08 15:41
Оценка:
Здравствуйте, -Sergey-, Вы писали:

S>проблема в следующем: создается новый объект, у которого есть отношение один ко многим к другому классу, в данный Лист добавляются новые экземпляры при сохранении базового класса происходит ексепшин, ругается на отсуствие foreignkey — нов базеон есть, скорее всего напутал где-то с аннотациями но самому найти не удалось ..

S>Caused by: org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544466. violation of FOREIGN KEY constraint "FK3454C9E6497E4391" on table "PAYMENT"
S>Foreign key reference target does not exist

Английский стоит подучить. Ругается не на отсутствие Foreign key. А на отсутствие Foreign key reference target.
То есть payment.billId ссылается на bill.billId. Но в payment.billId находится значение которого нет в bill.billId.
Почему так происходит другой вопрос. Не помню как там хибер ключи проставляет. Пробовал у payment устанавливать bill. Перед сохранением?
Re[2]: hibernate annotation one-to-many
От: Blazkowicz Россия  
Дата: 12.03.08 15:43
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Почему так происходит другой вопрос.

Ещё попорбуй убрать NOT NULL с payment.billID если он там есть.
Re[3]: hibernate annotation one-to-many
От: -Sergey- Украина  
Дата: 12.03.08 16:07
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

попробывал предложенные варианты не помогло.. но все равно спасибо за участие..
может у кого еще есть какие-то предложения..
-
[color="gray"]
Цель в жизни определяет все..
Выбор есть всегда..
Но мы часто не хотим его делать..
[/color]
Re[4]: hibernate annotation one-to-many
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 12.03.08 16:24
Оценка:
Здравствуйте, -Sergey-, Вы писали:

S>может у кого еще есть какие-то предложения..

Во-первых, если сконфигурить логирование так:
log4j.logger.org.hibernate.SQL=DEBUG, HIB
log4j.additivity.org.hibernate.SQL=false
## log hibernate prepared statement parameter values
log4j.logger.org.hibernate.type=DEBUG, HIB
log4j.additivity.org.hibernate.type=false

то ты сможеш увидеть какие именно значения инсертятся в базу.

S>
S>       Bill bill = new Bill();
>        Payment payments = new Payment();
>        bill.getPayments().add( payment2 );
S>


добавь еще строчку

    payments.setBill(bill);
Я ненавижу Hibernate!
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[5]: hibernate annotation one-to-many
От: -Sergey- Украина  
Дата: 12.03.08 16:45
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>Здравствуйте, -Sergey-, Вы писали:


S>>
S>>       Bill bill = new Bill();
>>        Payment payments = new Payment();
>>        bill.getPayments().add( payment2 );
          payments.setBill( bill );
S>>


пробывал тот же результат

остальное не возможности проверить сейчас
debug показал что значение bill устанавливается верно, затычка где-то в хибере.
очень не хочется возвращаться к старому способу — описывать все через xml//
-
[color="gray"]
Цель в жизни определяет все..
Выбор есть всегда..
Но мы часто не хотим его делать..
[/color]
Re: hibernate annotation one-to-many
От: 6lackbird Россия  
Дата: 12.03.08 17:29
Оценка:
Здравствуйте, -Sergey-, Вы писали:

<skipped>

Попробуй для

 @OneToMany( fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "paymentId")
    public Set<Payment> getPayments()
    {
        return payments;
    }


добавить @JoinColumn( name = "billId" )
"Мы будем уничтожать свое ядерное оружие вместе с Америкой" (c) Б. Ельцин
Re[6]: hibernate annotation one-to-many
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 12.03.08 17:43
Оценка:
Здравствуйте, -Sergey-, Вы писали:

S>debug показал что значение bill устанавливается верно, затычка где-то в хибере.


а в payment что инсертится?
Я ненавижу Hibernate!
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re: hibernate annotation one-to-many
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 12.03.08 17:48
Оценка:
Здравствуйте, -Sergey-, Вы писали:

S>
S>@Entity
S>@Table( name = "Bill" )
S>public class Bill
S>{
S>    @OneToMany( fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "paymentId")
S>    public Set<Payment> getPayments()
S>}
S>


Кстати, тут должно быть mappedBy="bill"
Я ненавижу Hibernate!
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[2]: hibernate annotation one-to-many
От: -Sergey- Украина  
Дата: 12.03.08 21:20
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>Здравствуйте, -Sergey-, Вы писали:


S>>
S>>@Entity
S>>@Table( name = "Bill" )
S>>public class Bill
S>>{
S>>    @OneToMany( fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "paymentId")
S>>    public Set<Payment> getPayments()
S>>}
S>>


ANS>Кстати, тут должно быть mappedBy="bill"


вопрос решил.. наешл доку на hibernate.org и сделал как было написанно, ноу меня остался вопрос ( выяснять его сегодня уже не стал спать хочется) а так понял mappedBy ??определяет главного в этой 2-хстор-й связке ??
а @JoinColumn( name = "fk_bill") просто задает имя присоединенному столбцу?


 public Bill() {
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long getBillId() {
        return billId;
    }

    public void setBillId(long billId) {
        this.billId = billId;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    @OneToMany(mappedBy = "bill", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    public Set<Payment> getPayments() {
        return payments;
    }

    public void setPayments(Set<Payment> payments) {
        this.payments = payments;
    }



@Entity
@Table(name = "Payment")
public class Payment {

    private long paymentId;
    private String caption;
    private Bill bill;


    public Payment() {
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public long getPaymentId() {
        return paymentId;
    }

    public void setPaymentId(long paymentId) {
        this.paymentId = paymentId;
    }

    public String getCaption() {
        return caption;
    }

    public void setCaption(String caption) {
        this.caption = caption;
    }

    @ManyToOne
    @JoinColumn( name = "fk_bill")
    public Bill getBill() {
        return bill;
    }

    public void setBill(Bill bill) {
        this.bill = bill;
    }
}
-
[color="gray"]
Цель в жизни определяет все..
Выбор есть всегда..
Но мы часто не хотим его делать..
[/color]
Re[3]: hibernate annotation one-to-many
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 13.03.08 08:40
Оценка:
Здравствуйте, -Sergey-, Вы писали:

S>вопрос решил.. наешл доку на hibernate.org и сделал как было написанно, ноу меня остался вопрос ( выяснять его сегодня уже не стал спать хочется) а так понял mappedBy ??определяет главного в этой 2-хстор-й связке ??


1.3.6 Working bi-directional links:

First, keep in mind that Hibernate does not affect normal Java semantics. How did we create a link between a Person and an Event in the unidirectional example? We added an instance of Event to the collection of event references, of an instance of Person. So, obviously, if we want to make this link working bi-directional, we have to do the same on the other side — adding a Person reference to the collection in an Event. This "setting the link on both sides" is absolutely necessary and you should never forget doing it.
/.../
What about the inverse mapping attribute? For you, and for Java, a bi-directional link is simply a matter of setting the references on both sides correctly. Hibernate however doesn't have enough information to correctly arrange SQL INSERT and UPDATE statements (to avoid constraint violations), and needs some help to handle bi-directional associations properly. Making one side of the association inverse tells Hibernate to basically ignore it, to consider it a mirror of the other side. That's all that is necessary for Hibernate to work out all of the issues when transformation a directional navigation model to a SQL database schema. The rules you have to remember are straightforward: All bi-directional associations need one side as inverse. In a one-to-many association it has to be the many-side, in many-to-many association you can pick either side, there is no difference.


S>а @JoinColumn( name = "fk_bill") просто задает имя присоединенному столбцу?


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

ЗЫ. Самое интересное, что пример в этой главе 1.3.6 "опасный" для использования. Так что читайте доки...
Я ненавижу Hibernate!
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[4]: hibernate annotation one-to-many
От: -Sergey- Украина  
Дата: 13.03.08 12:36
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>1.3.6 Working bi-directional links:

спасибо за приведенный текст.. прочитал и задался вопросом где тут упоминание mappedBy? с инверс все понятно — он помогает хиберу определить что первостепенно. мне были интересны аннотации как средство уйти от мапинга в xml файлы. убрать лишнее из проекта
Излишнее цитирование удалено. Автору строгий выговор.
-
[color="gray"]
Цель в жизни определяет все..
Выбор есть всегда..
Но мы часто не хотим его делать..
[/color]
Re[5]: hibernate annotation one-to-many
От: Blazkowicz Россия  
Дата: 13.03.08 12:43
Оценка:
Здравствуйте, -Sergey-, Вы писали:

S>мне были интересны аннотации как средство уйти от мапинга в xml файлы. убрать лишнее из проекта

ИМХО, xml для ORM маппинга заруливает аннотации. А лишнее оно никуда не делось. Оно просто из одной формы перетекло в другую. Хотя конечно же есть и некоторые плюсы.
Re[5]: hibernate annotation one-to-many
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 13.03.08 14:19
Оценка:
Здравствуйте, -Sergey-, Вы писали:

S>спасибо за приведенный текст.. прочитал и задался вопросом где тут упоминание mappedBy?


В доке по аннотациям:

The association may be bidirectional. In a bidirectional relationship, one of the sides (and only one) has to be the owner: the owner is responsible for the association column(s) update. To declare a side as not responsible for the relationship, the attribute mappedBy is used. mappedBy refers to the property name of the association on the owner side. In our case, this is passport. As you can see, you don't have to (must not) declare the join column since it has already been declared on the owners side.

If no @JoinColumn is declared on the owner side, the defaults apply. A join column(s) will be created in the owner table and its name will be the concatenation of the name of the relationship in the owner side, _ (underscore), and the name of the primary key column(s) in the owned side. In this example passport_id because the property name is passport and the column id of Passport is id.

Я ненавижу Hibernate!
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.