Mapping mit Annotations von 2 Tabellen

Hi zusammen,

ich steh auf dem Schlauch, habe folgendes Problem:

Ist Tabellen in der DB:

Table "customer":

Code:
+----------------+--------------+------+-----+---------+----------------+
| Field          | Type         | Null | Key | Default | Extra          |
+----------------+--------------+------+-----+---------+----------------+
| id             | int(11)      | NO   | PRI | NULL    | auto_increment |
| customernumber | bigint(8)    | NO   | MUL | NULL    |                |
| company        | varchar(250) | YES  |     | NULL    |                |
| salutation     | int(11)      | YES  | MUL | NULL    |                |
| firstname      | varchar(250) | YES  |     | NULL    |                |
| lastname       | varchar(250) | YES  |     | NULL    |                |
| address        | varchar(250) | YES  |     | NULL    |                |
| code           | int(11)      | YES  |     | NULL    |                |
| city           | varchar(250) | YES  |     | NULL    |                |
| country        | varchar(250) | YES  |     | NULL    |                |
| mobile         | varchar(250) | YES  |     | NULL    |                |
| private        | varchar(250) | YES  |     | NULL    |                |
| business       | varchar(250) | YES  |     | NULL    |                |
| email          | varchar(250) | YES  |     | NULL    |                |
| fullname       | varchar(250) | YES  |     | NULL    |                |
| phoneBusiness  | varchar(255) | YES  |     | NULL    |                |
| phonePrivate   | varchar(255) | YES  |     | NULL    |                |
+----------------+--------------+------+-----+---------+----------------+
Table "task":

Code:
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| tasknr      | bigint(8)    | YES  |     | NULL    |                |
| customer    | int(11)      | YES  | MUL | NULL    |                |
| name        | varchar(250) | YES  |     | NULL    |                |
| description | varchar(250) | YES  |     | NULL    |                |
| categorie   | int(11)      | YES  | MUL | NULL    |                |
| done        | tinyint(1)   | YES  |     | NULL    |                |
| project     | int(11)      | YES  | MUL | NULL    |                |
| bill        | int(11)      | YES  |     | NULL    |                |
| idinvoice   | int(11)      | YES  |     | NULL    |                |
| time        | double       | YES  |     | NULL    |                |
| total       | double       | YES  |     | NULL    |                |
| date        | date         | YES  |     | NULL    |                |
| dateTask    | datetime     | YES  |     | NULL    |                |
| fullName    | varchar(255) | YES  |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
Klasse Task.java:

Code:
@Entity
@Table(name = "task")
public class Task {

    @Id
    @GeneratedValue
    @Column(name = "id")
    private int id;

    private String fullName;

    private long taskNr;

    @Column(name = "name")
    private String name;
    private String description;
    private String categorie;
    private boolean done;
    private boolean bill;
    private double time;
    private double total;
    private Date dateTask;

//    @JoinColumn(name = "id")
//    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
//    private List<Customer> customer;


//    private Customer customer;

    public Task(String fullName, long taskNr, String name, String description, String categorie, Boolean done,
                Boolean bill, double time, double total, Date date) {
        this.fullName = fullName;
        this.description = description;
        this.name = name;
        this.categorie = categorie;
        this.done = done;
        this.taskNr = taskNr;
        this.bill = bill;
        this.time = time;
        this.total = total;
        this.dateTask = date;
//        this.customer = customer;
    }

    public Task() {

    }


//    @OneToOne(cascade = CascadeType.ALL)
//    @JoinTable(
//            name = "customer",
//            joinColumns = @JoinColumn(name="id"),
//            inverseJoinColumns = @JoinColumn(name="customer")
//    )
//
//    @Column
//    @ElementCollection(targetClass = xx.xxx.models.Customer.class)
//    public List<Customer> getCustomer(){
//        return this.customer;
//    }
//
//    public void setCustomer (List<Customer> customer){
//        this.customer = customer;
//    }
Die Klasse Customer.java:

Code:
@Entity
@Table(name="customer")
public class Customer {

    @Id
    @GeneratedValue
    @Column(name="id")
    private int id;

    private long customerNumber;
    private String company;
    private String salutation;
    private String firstName;
    private String lastName;
    private String address;
    private int code;
    private String city;
    private String country;
    private String phonePrivate;
    private String phoneBusiness;
    private String mobile;
    private String email;

    @Column(name="fullname")
    private String fullName;


//    private List<Task> taskList;

    public Customer(){

    }

    public Customer(long customerNumber, String company, String salutation, String firstName, String lastName, String address,
                    int code, String city, String country, String phonePrivate, String phoneBusiness, String mobile,
                    String eMail, String fullName) {
        this.customerNumber = customerNumber;
        this.company = company;
        this.salutation = salutation;
        this.firstName = firstName;
        this.lastName = lastName;
        this.address = address;
        this.code = code;
        this.city = city;
        this.country = country;
        this.phonePrivate = phonePrivate;
        this.phoneBusiness = phoneBusiness;
        this.mobile = mobile;
        this.email = eMail;
        this.fullName = fullName;
    }

//    public void setTaskList(List<Task> taskList){
//        this.taskList = taskList;
//    }

//    @ManyToMany(cascade = CascadeType.ALL)
//    @JoinTable(name = "task")
//    public List<Task> getTaskList(){
//        return this.taskList;
//    }
Zum Verständnis:

So wie es jetzt gepostet ist, werden beiden Klassen geladen und die GUI Befüllt wie erwartet.

Ihr seht da Kommentierte Join statements... ich versuche entsprechend die Richtigen informationen zusammenzustellen, habe einiges an Literatur gelesen doch leider noch keine für mich funktionierende Lösung...

Wenn ich versuche die Tabellen zusammen zu führen habe ich folgende Error Meldung in der Console:

Code:
org.hibernate.AnnotationException: @OneToOne or @ManyToOne on xx.xxx.models.Task.customer references an unknown entity: java.util.List
Der funktionierende SQL Query String ist:

Code:
String query = "select task.id, task.tasknr, customer.fullname as fullname, task.name, task.description, " +
        "task.done, task.project, categorie.name as categorie\n, task.bill, task.time, task.total, task.date " +
        "from task\n" +
        "left join categorie on task.categorie = categorie.id " +
        "left join customer on task.customer = customer.id";
Wobei ich die categorie noch auslasse, muss es erst mit dem Task und Customer zum laufen kriegen.

habt ihr eine idee?
 
Du hast eine 1:n-Beziehung zwischen Customer und Task. Dem entsprechend gehört zu einem Task nur ein Customer-Objekt und keine Liste von Customer-Objekten.

Task:
Java:
    @ManyToOne
    private Customer customer;
Customer:
Java:
    @OneToMany(mappedBy="customer")
    private List<Task> tasks;
 
vielen dank mihe7!

jedoch erscheint mir bei der abfrage noch keine zusammenführung stattgefunden zu haben?

Code:
tableColumnTaskDate.setCellValueFactory(new PropertyValueFactory<Task, Date>("dateTask"));
tableColumnCustomer.setCellValueFactory(new PropertyValueFactory<Customer, String>("fullName"));
tableColumn01.setCellValueFactory(new PropertyValueFactory<Task, String>("name"));
tableColumn02.setCellValueFactory(new PropertyValueFactory<Task, String>("description"));
tableColumn03.setCellValueFactory(new PropertyValueFactory<Task, String>("categorie"));
tableColumn04.setCellValueFactory(new PropertyValueFactory<Task, Boolean>("done"));

tableViewMain.setItems(getTasks());
die getTasks Funktion:

Code:
 private ObservableList<Task> getTasks() throws SQLException {
        ObservableList<Task> tasksList = FXCollections.observableArrayList();

        Configuration cfg = new Configuration().configure("/configs/hibernate.cfg.xml");
        SessionFactory sessionFactory = cfg.buildSessionFactory();


        Session session = sessionFactory.openSession();
        Transaction tx = null;

        try {
            tx = session.beginTransaction();
            List tasks = session.createQuery("FROM Task").list();
            for (Iterator iterator = tasks.iterator(); iterator.hasNext();){
                Task task = (Task) iterator.next();
                System.out.println("Task Nr: " + task.getTaskNr());
            }
            tasksList = FXCollections.observableArrayList(session.createQuery("FROM Task").list());
            tx.commit();
        } catch (HibernateException e) {
            if (tx!=null) tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }

//        SqlHelperTasks SqlHelper = new SqlHelperTasks();

//        tasks = SqlHelper.getTasks();
        return tasksList;
    }
 
Das ist seltsam, denn standardmäßig wird eine ManyToOne sofort geladen (fetch=FetchType.EAGER). Probier mal folgende Abfrage: "SELECT t FROM Task t LEFT JOIN FETCH t.customer c".

Übrigens: Du führst die Abfrage aktuell doppelt aus. Das muss nicht sein. Eine ObservableList ist auch nur eine List.

EDIT: LEFT JOIN verwendet.
 
Zuletzt bearbeitet:
nach wie vor wird Customer nicht geladen.

ja ich weiss :)
die zweite abfrage ist lediglich für einen sysoutput :)

output von console:
Code:
Hibernate: 
    select
        task0_.id as id0_0_,
        customer1_.id as id1_1_,
        task0_.bill as bill0_0_,
        task0_.categorie as categorie0_0_,
        task0_.customer_id as customer11_0_0_,
        task0_.dateTask as dateTask0_0_,
        task0_.description as descript5_0_0_,
        task0_.done as done0_0_,
        task0_.name as name0_0_,
        task0_.taskNr as taskNr0_0_,
        task0_.time as time0_0_,
        task0_.total as total0_0_,
        customer1_.address as address1_1_,
        customer1_.city as city1_1_,
        customer1_.code as code1_1_,
        customer1_.company as company1_1_,
        customer1_.country as country1_1_,
        customer1_.customerNumber as customer7_1_1_,
        customer1_.email as email1_1_,
        customer1_.firstName as firstName1_1_,
        customer1_.fullname as fullname1_1_,
        customer1_.lastName as lastName1_1_,
        customer1_.mobile as mobile1_1_,
        customer1_.phoneBusiness as phoneBu13_1_1_,
        customer1_.phonePrivate as phonePr14_1_1_,
        customer1_.salutation as salutation1_1_ 
    from
        task task0_ 
    left outer join
        customer customer1_ 
            on task0_.customer_id=customer1_.id
 
Das Problem muss an anderer Stelle sein. Um ganz sicher zu gehen, kannst Du ja spaßeshalber mal unmittelbar vor dem return taskList; noch einfügen:
Java:
for (Task t : taskList) {
    System.out.println(t.getId() + ": " + (t.getCustomer() == null ? "-----" : t.getCustomer().getId()));
}
 
ja das denke ich auch aber wo? :)

Code:
1: -----
2: -----
3: -----
4: -----
5: -----
6: -----
7: -----
8: -----
9: -----
10: -----
11: -----
12: -----
13: -----
14: -----
15: -----
16: -----
was mir noch nich klar ist, wie weiss aufgrund der annotations hibernate, dass es Customer joinen muss?
 
Passen die Fremdschlüssel?

Wenn ich das grad richtig sehe, heißt der in der Task-Tabelle customer, in den späteren Statements steht aber customer_id (kann aber gut sein, das ich grad völlig falsch gelesen habe und denke...)
 
also der key in der Task Tabelle heisst customer richtig.

dieser referenziert die Spalte Id von der Tabelle Customer.

ich bin der meinung dass es stimmt, ansosten würde mein SQL Statement nicht funktionieren.
 
leider...
java -jar hbtest-src.jar
no main manifest attribute, in hbtest-src.jar

wenndu mir aber die source gibst, dann kann ich es mir anschauen :)
 
ich bin der meinung dass es stimmt, ansosten würde mein SQL Statement nicht funktionieren.
Weiß Hibernate auch, dass die Spalte customer und nicht customer_id heißt?

In der von dir gezeigten Konsolenausgabe steht task0_.customer_id und eben nicht nur task0_.customer (wie es auch in deinem eigenen SQL-Statement steht)
 
zwischen demo code von mihe7 und dein input mrBrown.. hab ich das nun auch "realisiert".

ich hab in der DB nun zwecks test die Spalte angepasst und dessen name von customer zu customer_id umgestellt:

siehe da, ein schritt weiter!

Code:
1: 26
2: 27
3: 26
4: 29
5: 27
6: 29
7: 29
8: 29
9: 27
10: 27
11: 27
12: 29
13: 27
14: 27
15: 26
16: 27
17: 26
18: 26
19: 31
20: 31
also es wird nun tatsächlich eine id ausgelesen.

Im Debug modus habei ch auch die objekte anschauen können es sind tatsächlcih die entsprechende einträge drinn.

das nächste ist zu wissen wieso es nicht in der tableview angezeigt wird?
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben