Hibernate mapping question...
От: BeerKiller  
Дата: 21.08.05 23:02
Оценка:
доброго времени суток!

осваиваю hibernate, столкнулся с задачей, общий смысл которой сводится к следующему:

есть классы:

public class Person {
  private long id;
  private String name;
  private int age;
  // ...
  // getters/setters
}

public class Car {
  private long id;
  private String model;
  private String color;
  // ...
  // getters/setters

}

public class TakenCar {
  private long id;
  private Person person;
  private Car car;
  // ...
  // getters/setters
}


есть так же таблицы (*PrimaryKey):

PERSONS (*P_ID, P_NAME, P_AGE)
CARS (*C_ID, C_MODEL, C_COLOR)
TAKENCARS (*TC_ID, P_ID, C_ID)

соответственно связи:

PERSONS.P_ID <1---*> TAKENCARS.P_ID
CARS.C_ID <1---*> TAKENCARS.C_ID

вот так я это пытаюсь мапить:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    
    <class name="Person" table="PERSON">
        <id name="id" type="long" column="P_ID">
            <generator class="increment"/>
        </id>
        <property name="name" column="P_NAME"/>
        <property name="age" column="P_AGE"/>
    </class>
    
    <class name="Car" table="CARS">
        <id name="id" type="long" column="C_ID">
            <generator class="increment"/>
        </id>
        <property name="model" column="C_MODEL"/>
        <property name="color" column="C_COLOR"/>
    </class>
    
    <class name="TakenCar" table="TAKENCARS">
        <id name="id" type="long" column="TC_ID">
            <generator class="increment"/>
        </id>
        <!-- здесь и вопрос: как правильно 
                смапить связи и нужно ли вставлять
                в этот класс свойства для полей
                P_ID и C_ID таблицы TAKENCARS ? -->
    </class>
    
</hibernate-mapping>


заранее большое спасибо!
Re: Hibernate mapping question...
От: deepsky Украина  
Дата: 22.08.05 10:12
Оценка:
Здравствуйте, BeerKiller, Вы писали:
....
BK>соответственно связи:

BK>PERSONS.P_ID <1---*> TAKENCARS.P_ID

BK>CARS.C_ID <1---*> TAKENCARS.C_ID

Есть два варианта:
первый — ваш подход, с использованием маппинга для таблицы связей

<hibernate-mapping>
    <class name="Person" table="PERSONS">
        <id name="id" type="long" column="P_ID">
            <generator class="sequence"/>
        </id>
        <property name="name" type="string" column="P_NAME"/>
        <property name="age" type="int" column="P_AGE"/>
    </class>
    <class name="Car" table="CARS">
        <id name="id" type="long" column="C_ID">
            <generator class="sequence"/>
        </id>
        <property name="model" type="string" column="C_MODEL"/>
        <property name="color" type="string" column="C_COLOR"/>
    </class>
    <class name="TakenCar" table="TAKENCARS">
        <id name="id" type="long" column="TC_ID">
            <generator class="sequence"/>
        </id>

        <!-- здесь и вопрос: как правильно
                смапить связи и нужно ли вставлять
                в этот класс свойства для полей
                P_ID и C_ID таблицы TAKENCARS ? -->

        <many-to-one name="person" class="Person" column="P_ID"/>
        <many-to-one name="car" class="Car" column="C_ID"/>
    </class>
</hibernate-mapping>


второй — с использованием маппинга многие ко многим. В TAKENCARS нужно будет удалить колонку
с первичным ключем, и в каждый из классов Car и Person добавить коллекцию элементов:

<hibernate-mapping>
    <class name="Person" table="PERSONS">
        <id name="id" type="long" column="P_ID">
            <generator class="sequence"/>
        </id>
        <property name="name" type="string" column="P_NAME"/>
        <property name="age" type="int" column="P_AGE"/>
        <set name="cars" table="TAKENCARS" cascade="all">
            <key column="P_ID"/>
            <many-to-many column="C_ID" class="Car"/>
        </set>
    </class>

    <class name="Car" table="CARS">
        <id name="id" type="long" column="C_ID">
            <generator class="sequence"/>
        </id>
        <property name="model" type="string" column="C_MODEL"/>
        <property name="color" type="string" column="C_COLOR"/>
        <set name="persons" table="TAKENCARS" inverse="true" cascade="all">
            <key column="C_ID"/>
            <many-to-many column="P_ID" class="Person"/>
        </set>
    </class>
</hibernate-mapping>


Второй вариант посложнее, но пожалуй более ближе к объектной модели.
Re[2]: Hibernate mapping question...
От: BeerKiller  
Дата: 22.08.05 12:29
Оценка:
Здравствуйте, deepsky, Вы писали:

D>Есть два варианта:

D>первый — ваш подход, с использованием маппинга для таблицы связей

делал (почти) так же. весь вечер документацию читал, ближе к 3 часам ночи уже не различал many_to_one и many-to-one ))))
теперь все работает.

но возник другой вопрос (

при таком мапинге говорится что не найдены геттеры и сеттеры (для ID) для
полей person и car в классе TakenCar. предположим это можно изобразить
вот так:

public long getPersonId(){
  return person.getId();
}
public void setPersonId(long id){
  person.setId(id)
}
public long getCarId(){
  return car.getId();
}
public void setCarId(long id){
  car.setId(id)
}


пытаюсь сохранить объект TakenCar:

public static void main(String[] args){
        
    Session session = HibernateUtil.currentSession();
    Transaction tx = session.beginTransaction();
        
    Person person = new Person();
    person.setName("Some_name");
    person.setAge(35);
    Car car = new Car();
    car.setModel("Some_model");
    car.setColor("green");
    session.save(person);
    session.save(car);
    TakenCar takencar = new TakenCar();
    takencar.setPerson(person);
    takencar.setCar(car);
    session.save(takencar);

    tx.commit();
    HibernateUtil.closeSession();
}


объекты car и person сохраняются, а в месте
session.save(takencar);
возникает ексепшн.
вот строки из аутпута:

Exception in thread "main" org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of Person.id
...
Causing by: java.lang.IlegalArgumentException: object is not an instance of declaring class
...


как это чинить? или где об этом почитать?

заранее большое спасибо!
Re[3]: Hibernate mapping question...
От: deepsky Украина  
Дата: 22.08.05 12:51
Оценка:
Здравствуйте, BeerKiller, Вы писали:

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

BK>но возник другой вопрос (
BK>при таком мапинге говорится что не найдены геттеры и сеттеры (для ID) для
BK>полей person и car в классе TakenCar. предположим это можно изобразить
BK>вот так:

BK>
BK>public long getPersonId(){
BK>  return person.getId();
BK>}
BK>public void setPersonId(long id){
BK>  person.setId(id)
BK>}
BK>public long getCarId(){
BK>  return car.getId();
BK>}
BK>public void setCarId(long id){
BK>  car.setId(id)
BK>}
BK>


Для всех филдов в классе, для которых есть мапинг, должны быть сеттеры/геттеры, иначе хибернейт не сможет им присвоить значения.
Что касается TakenCar — если у вас такой же маппинг как в первом варианте, тогда нужно в
класс TakenCar добавить два поля — person и car, соответствующих классов и с соответствующими геттерами/сетеррами.
Этого должно хватить.
Или приведите свой мапинг/определения классов.

BK>пытаюсь сохранить объект TakenCar:

BK>
public static void main(String[] args){

BK>    Session session = HibernateUtil.currentSession();
BK>    Transaction tx = session.beginTransaction();
        
BK>    Person person = new Person();
BK>    person.setName("Some_name");
BK>    person.setAge(35);
BK>    Car car = new Car();
BK>    car.setModel("Some_model");
BK>    car.setColor("green");
BK>    session.save(person);
BK>    session.save(car);
BK>    TakenCar takencar = new TakenCar();
BK>    takencar.setPerson(person);
BK>    takencar.setCar(car);
BK>    session.save(takencar);

BK>    tx.commit();
BK>    HibernateUtil.closeSession();
BK>}


BK>объекты car и person сохраняются, а в месте
session.save(takencar);
возникает ексепшн.

BK>вот строки из аутпута:

Вроде бы всё правильно, проблема скорее всего в мапинге TakenCar.

BK>как это чинить? или где об этом почитать?


Почитать — на хибернейт.орг, тут без вариантов.

BK>заранее большое спасибо!
Re[4]: Hibernate mapping question...
От: BeerKiller  
Дата: 22.08.05 13:18
Оценка:
Здравствуйте, deepsky, Вы писали:

D>Или приведите свой мапинг/определения классов.


классы:
public class Person {
  private long id;
  private String name;
  private int age;
  public Person() {
  }
  public long getId() {
    return id;
  }
  public void setId(long id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public int getAge() {
    return age;
  }
  public void setAge(int age) {
    this.age = age;
  }
}

public class Car {
  private long id;
  private String model;
  private String color;
  public Car() {
  }
  public long getId() {
    return id;
  }
  public void setId(long id) {
    this.id = id;
  }
  public String getModel() {
    return model;
  }
  public void setModel(String model) {
    this.model = model;
  }
  public String getColor() {
    return color;
  }
  public void setColor(String color) {
    this.color = color;
  }
}

public class TakenCar {
  private long id;
  private Person person;
  private Car car;
  public TakenCar() {
  }
  public long getId() {
    return id;
  }  
  public void setId(long id) {
    this.id = id;
  }
  public Person getPerson() {
    return person;
  }
  public void setPerson(Person person) {
    this.person = person;
  }  
  public Car getCar() {
    return car;
  }
  public void setCar(Car car) {
    this.car = car;
  }
  public long getPersonId() {
    return person.getId();
  }
  public void setPersonId(long personId) {
    person.setId(personId);
  }
  public long getCarId() {
    return car.getId();
  }
  public void setCarId(long carId) {
    car.setId(carId);
  }
}


мапинг:
<hibernate-mapping>
    <class name="Person" table="PERSONS">
        <id name="id" type="long" column="P_ID">
            <generator class="sequence"/>
        </id>
        <property name="name" type="string" column="P_NAME"/>
        <property name="age" type="int" column="P_AGE"/>
    </class>
    <class name="Car" table="CARS">
        <id name="id" type="long" column="C_ID">
            <generator class="sequence"/>
        </id>
        <property name="model" type="string" column="C_MODEL"/>
        <property name="color" type="string" column="C_COLOR"/>
    </class>
    <class name="TakenCar" table="TAKENCARS">
        <id name="id" type="long" column="TC_ID">
            <generator class="sequence"/>
        </id>
        <many-to-one name="person" class="Person" column="P_ID"/>
        <many-to-one name="car" class="Car" column="C_ID"/>
    </class>
</hibernate-mapping>


можно ли вообще смапить класс TakenCar если в нем нет свойств personId
и carId, а есть только объекты классов Person и Car (и свойство id)?

заранее большое спасибо!
Re[5]: Hibernate mapping question...
От: deepsky Украина  
Дата: 22.08.05 13:40
Оценка:
Здравствуйте, BeerKiller, Вы писали:



BK>мапинг:

BK>
BK><hibernate-mapping>
BK>    <class name="Person" table="PERSONS">
BK>        <id name="id" type="long" column="P_ID">
BK>            <generator class="sequence"/>
BK>        </id>
BK>        <property name="name" type="string" column="P_NAME"/>
BK>        <property name="age" type="int" column="P_AGE"/>
BK>    </class>
BK>    <class name="Car" table="CARS">
BK>        <id name="id" type="long" column="C_ID">
BK>            <generator class="sequence"/>
BK>        </id>
BK>        <property name="model" type="string" column="C_MODEL"/>
BK>        <property name="color" type="string" column="C_COLOR"/>
BK>    </class>
BK>    <class name="TakenCar" table="TAKENCARS">
BK>        <id name="id" type="long" column="TC_ID">
BK>            <generator class="sequence"/>
BK>        </id>
BK>        <many-to-one name="person" class="Person" column="P_ID"/>
BK>        <many-to-one name="car" class="Car" column="C_ID"/>
BK>    </class>
BK></hibernate-mapping>
BK>


BK>можно ли вообще смапить класс TakenCar если в нем нет свойств personId

BK>и carId, а есть только объекты классов Person и Car (и свойство id)?

personId и carId не нужны в TakenCar, возможно поэтому Session бросал эксепшен при сохранении инстанса TakenCar.

public class TakenCar {
  private long id;
  private Person person;
  private Car car;
  public TakenCar() {
  }
  public long getId() {
    return id;
  }  
  public void setId(long id) {
    this.id = id;
  }
  public Person getPerson() {
    return person;
  }
  public void setPerson(Person person) {
    this.person = person;
  }  
  public Car getCar() {
    return car;
  }
  public void setCar(Car car) {
    this.car = car;
  }
}
Re[6]: Hibernate mapping question...
От: BeerKiller  
Дата: 22.08.05 13:54
Оценка:
Здравствуйте, deepsky, Вы писали:

D>personId и carId не нужны в TakenCar, возможно поэтому Session бросал эксепшен при сохранении инстанса TakenCar.


BK> при таком мапинге говорится что не найдены геттеры и сеттеры (для ID) для

BK> полей person и car в классе TakenCar. предположим это можно изобразить
BK> вот так:

BK> public long getPersonId(){

BK> return person.getId();
BK> }
BK> public void setPersonId(long id){
BK> person.setId(id)
BK> }
BK> public long getCarId(){
BK> return car.getId();
BK> }
BK> public void setCarId(long id){
BK> car.setId(id)
BK> }

если нету этих геттеров и сеттеров при исходном маппинге
вылетает ексепшен при запуске.
строка из аутпута:
Caused by: org.hibernate.PropertyNofFoundException: Could not find a getter for personId in class TakenCar

лишь из-за этого я их добавил...

BK>можно ли вообще смапить класс TakenCar если в нем нет свойств personId

BK>и carId, а есть только объекты классов Person и Car (и свойство id)?

заранее большое спасибо!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.