Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / никак не въеду: EJB3 - связи между таблицами в коде - плиз хелп / 11 сообщений из 11, страница 1 из 1
06.08.2007, 23:13:38
    #34709141
J-Pro
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
никак не въеду: EJB3 - связи между таблицами в коде - плиз хелп
Ребят, помогите плиз... Перешёл в книжке "Manning - Ejb 3 In Action" к главе об аннотациях @OneToOne, @OneToMany и т.д. В купе с аннотацией @SecondaryTable я уже вообще ничего не понимаю...

Собственно, вопрос: есть у меня в базе(MS SQL 2K) две таблицы - Employees и Jobs. Первая описывает рабочих, вторая их работы(до текущей). SQL выглядит так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
CREATE TABLE [dbo].[t_employees] (
  [t_employee_id] int  IDENTITY( 1 ,  1 ) NOT  NULL ,
  [last_name]nvarchar( 64 ) NOT  NULL ,
  [first_name]nvarchar( 64 ) NOT  NULL ,
  [birth_date]datetime NOT  NULL ,
  [military_special]varchar( 35 ) CONSTRAINT [DF__t_employe__milit__78B3EFCA]  DEFAULT   1   NULL ,
  PRIMARY KEY CLUSTERED ([t_employee_id])
)
ON [PRIMARY]
GO

CREATE TABLE [dbo].[t_jobs] (
  [t_job_id] int  IDENTITY( 1 ,  1 ) NOT  NULL ,
  [t_employee_id] int  NOT  NULL ,
  [job_place]nvarchar( 240 ) NOT  NULL ,
  [speciality]nvarchar( 64 ) NOT  NULL ,
  PRIMARY KEY CLUSTERED ([t_job_id]),
  CONSTRAINT [t_job_history_fk] FOREIGN KEY ([t_employee_id]) 
  REFERENCES [dbo].[t_employees] ([t_employee_id]) 
  ON UPDATE NO ACTION
  ON DELETE CASCADE
)
ON [PRIMARY]
GO

У каждого работника может быть более одного рабочего места в прошлом(ну, сменил с десяток работ, к примеру, пока пришёл на текущую), но у одной "работы" может быть только один рабочий. Значит, отношение таблицы t_employees к t_jobs есть "один ко многим". В коде я описал данные таблицы в виде Entity Bean'ов, как:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
@Entity
@Table(name = "t_employees")
 public   class  Employee  implements  Serializable 
{
     private   static   final   long  serialVersionUID = 1L;

     private   int  employeeId;
     private  String lastName;
     private  String firstName;
     private  Date birthDate;
     private  String militarySpecial;


     public  Employee() 
    {
    }

    @Id
    @Column(name = "t_employee_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
     public   int  getEmployeeId()
    {
         return   this .employeeId;
    }

     public   void  setEmployeeId( int  employeeId)
    {
         this .employeeId = employeeId;
    }

    @Column(name = "birth_date")
     public  Date getBirthDate()
    {
         return   this .birthDate;
    }

     public   void  setBirthDate(Date birthDate)
    {
         this .birthDate = birthDate;
    }

    @Column(name = "first_name")
     public  String getFirstName()
    {
         return   this .firstName;
    }

     public   void  setFirstName(String firstName)
    {
         this .firstName = firstName;
    }

    @Column(name = "last_name")
     public  String getLastName()
    {
         return   this .lastName;
    }

     public   void  setLastName(String lastName)
    {
         this .lastName = lastName;
    }

    @Column(name = "military_special")
     public  String getMilitarySpecial()
    {
         return   this .militarySpecial;
    }

     public   void  setMilitarySpecial(String militarySpecial)
    {
         this .militarySpecial = militarySpecial;
    }

}

@Entity
@Table(name = "t_jobs")
 public   class  Job  implements  Serializable 
{
     private   static   final   long  serialVersionUID = 1L;

     private   int  jobId;
     private   int  employeeId;
     private  String jobPlace;
     private  String speciality;

     public  Job() 
    {
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "t_job_id")
     public   int  getJobId() 
    {
		 return   this .jobId;
    }

     public   void  setJobId( int  jobId) 
    {
         this .jobId = jobId;
    }

    @Column(name = "t_employee_id")
     public   int  getEmployeeId()
    {
         return  employeeId;
    }

     public   void  setEmployeeId( int  employeeId)
    {
         this .employeeId = employeeId;
    }

    @Column(name = "job_place")
     public  String getJobPlace()
    {
         return  jobPlace;
    }

     public   void  setJobPlace(String jobPlace)
    {
         this .jobPlace = jobPlace;
    }

    @Column(name = "speciality")
     public  String getSpeciality()
    {
         return  speciality;
    }

     public   void  setSpeciality(String speciality)
    {
         this .speciality = speciality;
    }

}

Вот. НО, самое главное - что использовать для описания связей между этими двумя таблицами - я ума не приложу... Честно, читаю книжку и не понимаю как это использовать. Как указать, что поле employeeId в бине Job является Foreign Key для бина Employee? У кого-то есть опыт написания такого кода? Кто как пишет? Подскажите новичку, я только разбираюсь с EJB, хотелось бы вникнуть...

И второй вопрос, тоже, может, кто знает... как в бине Employee указать, что militarySpecial является 1 по умолчанию, как добавить CONSTRAINT в бине? Видимо, как-то в аннотации @Table, с помощью UniqueConstraint, но как конкретно?

Огромное спасибо заранее.


P.S.: на самом деле полей в таблицах больше, но они без связей, поэтому я их не включал сюда, дабы сэкономить место.
...
Рейтинг: 0 / 0
07.08.2007, 09:20:59
    #34709422
yanich
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
никак не въеду: EJB3 - связи между таблицами в коде - плиз хелп
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
 public   class  Employee  implements  Serializable 
{
    ...
    @OneToMany(mappedBy = "emp")
     private  List<Job> jobList;
    ...
}

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
 public   class  Job  implements  Serializable 
{
     ...
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "t_employee_id", referencedColumnName = "t_employee_id") 
    /* Первое t_employee_id - столбец в таблице t_jobs, второе - в таблице t_employees 
- мой совет дай им разные имена, чтоб не путаться */
     private  Employee emp;
    ...
}
...
Рейтинг: 0 / 0
07.08.2007, 22:22:06
    #34712426
J-Pro
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
никак не въеду: EJB3 - связи между таблицами в коде - плиз хелп
Спасибо большое, параллельно чтению литературы буду пробовать!

Ещё вопрос возник... А как добавлять эти две ентити в базу? По идее, создавать несколько Jobs, потом создать один Employee, кинуть Jobs в список к Employee(пока ещё не вызывая persist ни у того, ни у другого), а потом em.persist(Employee) ?

Ещё раз спасибо!

P.S.: Обо всём этом я ещё прочитаю, т.к. читаю две книжки. Но дело в том, что задачу нужно выполнить сейчас, поэтому и пытаюсь быстро разобраться, а затем уже "догонять" по книжке. Просто, читая книгу, я не успею всё реализовать... Спасибо за понимание.
...
Рейтинг: 0 / 0
07.08.2007, 22:34:03
    #34712437
J-Pro
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
никак не въеду: EJB3 - связи между таблицами в коде - плиз хелп
Да... и ещё один вопрос... В связи с тем, что у Job появился private Employee emp; нужен ли ещё private int employeeId; ?
...
Рейтинг: 0 / 0
08.08.2007, 01:29:53
    #34712565
J-Pro
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
никак не въеду: EJB3 - связи между таблицами в коде - плиз хелп
Сделал тут как посоветовали. Пришлось убрать обьявление поля t_employee_id из бина Job, потому что ругался JBoss.

Ну в общем, если честно, то я не понимаю, зачем нужны эти аннотации, потому как по-любому добавлять нужно всё в отдельности. Даже если я создаю Employee, инициализирую его данными, потом создаю список Jobs(предварительно каждый проинициализировав), заношу их в БД(persist'ом), затем кидаю их в список и присваиваю списку из Employee, добавляя затем сам Employee(persist'ом), это ничего не меняет. В том плане, что у каждого из этих Job в базе в столбце "t_employee_id" стоит NULL.

Странно, скорее всего, конечно, я чего-то недопонял... но буду пробовать ещё. (то, что нужно читать доки я в курсе, это и делаю, но... выше объяснил)
...
Рейтинг: 0 / 0
08.08.2007, 09:24:16
    #34712758
yanich
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
никак не въеду: EJB3 - связи между таблицами в коде - плиз хелп
Все-таки совет прочитать все до конца, а не лезть вперед паровоза - ничего хорошего из этого не выйдет...
Что касается persist-ов у Employee и Job:
Создали Employee -> проинициализировали его атрибуты -> Создали несколько Job-ов -> присвоили каждому из них Employee emp -> добавили их в список jobList, созданного на первом этапе Employee -> и сказали employee.persist();

P.S.
Это конечно сработает, если
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
 public   class  Employee  implements  Serializable 
{
    ...
    @OneToMany(mappedBy = "emp", cascade={CascadeType.PERSIST, CascadeType.REMOVE})
     private  List<Job> jobList;
    ...
}
...
Рейтинг: 0 / 0
08.08.2007, 17:09:10
    #34714692
J-Pro
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
никак не въеду: EJB3 - связи между таблицами в коде - плиз хелп
Ещё раз большое спасибо. Конечно, буду читать...
...
Рейтинг: 0 / 0
16.08.2007, 01:18:45
    #34730998
J-Pro
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
никак не въеду: EJB3 - связи между таблицами в коде - плиз хелп
Ещё раз благодарю за помощь, предыдущие примеры сработали на "ура".

Только, вот, при тех же связях в Entity бинах, почему-то не получается получить employee, у которого бы сразу был бы список всех job. Хотя, связи есть... Не подскажете, может, как-то по-особенному брать надо? Я сейчас делаю так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
        List<Employee> list;

         try 
        {
            list = em.createQuery("FROM Employee").getResultList();
        }
         catch (Exception ex)
        {
            System.out.println("Exception in getAll: " + ex.toString());
            list =  null ;
        }

Ну и дальше использую список. Т.е. выбираю записи с помощью JPQL. Надеялся, что это поможет выбрать не только всех рабочих, но и заполнить их список jobList у каждого из элементов списка list, что в листинге выше. Но последнего не происходит :(

Заранее спасибо за помощь.
...
Рейтинг: 0 / 0
16.08.2007, 12:10:18
    #34731906
expp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
никак не въеду: EJB3 - связи между таблицами в коде - плиз хелп
неясно, что неясно ....

1. если jobList.isEmpty() то наверно в базе так и есть. и проблемы в сохранении объектов

2. если тебя возмущает SQL запросы при навигации по этим коллекциям, то надо использовать слово fetch в запросе
...
Рейтинг: 0 / 0
16.08.2007, 16:05:39
    #34732932
J-Pro
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
никак не въеду: EJB3 - связи между таблицами в коде - плиз хелп
exppнеясно, что неясно .... Хм.. ну неясно следующее: почему при существующих(прописанных аннотациями) связях между entity bean'ами, при добавлении только лишь employee(со списком job'ов), в базу ложатся и работник, и его работы. А при изъятии из базы всех записей employee, списки jobList у них не заполняются, как-будто в базе нет связанных с ними работ. Но на самом-то деле они есть и занесены были перед изъятием. Вот и спрашиваю, может, запрос как-то по-другому надо определять? Но с другой стороны, хибер видит, что есть у employee свойство jobList типа List<Job>, что связано оно с таблицей работ. Почему бы не заполнить?

(Не исключено, что я ещё какой-то мелочи не знаю просто)


expp1. если jobList.isEmpty() то наверно в базе так и есть. Нет, в базе таблицы тоже связаны Foreign Key'ем, который является ID работника и находится в таблице t_jobs.
...
Рейтинг: 0 / 0
16.08.2007, 17:58:15
    #34733375
J-Pro
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
никак не въеду: EJB3 - связи между таблицами в коде - плиз хелп
Да, блин, всё от недостаточного знания всего материала... Оказывается, списки есть, всё нормально и если их вывести в сешшн бине, они выводятся нормально. А если вернуть список рабочих(в каждом из которых есть списки их работ), то рабочие возвращаются нормально, а при обращении к спискам их работ, происходит
Код: plaintext
1.
 16 . 08 . 2007   15 : 58 : 39  org.hibernate.LazyInitializationException <init>
SEVERE: failed to lazily initialize a collection of role: netinfo.hrdslr.persistence.Employee.jobs, no session or session was closed

Буду искать что и как :(
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / никак не въеду: EJB3 - связи между таблицами в коде - плиз хелп / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]