• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Could not determine recommended JdbcType for

Object Storage Arubacloud
0 głosów
1,921 wizyt
pytanie zadane 10 grudnia 2022 w Java przez letmestay Użytkownik (520 p.)
przywrócone 10 grudnia 2022 przez letmestay

Rozkładam ręce nad tym błędem. Od razu powiem, że pierwszy raz korzystam z javy i frameworków. Za zadanie mam stworzenie bazy na podstawie klas encyjnych (baza ma się generować z kodu). Mam dwie klasy Cars i Clients oraz klase Rents, z ktorą mają mieć relacje one to many.

Klasa Clients:

package database;

import jakarta.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "Clients")

public class Clients {
    private int id;
    private String name;
    private String surname;

    @OneToMany(mappedBy = "clients")
    private Set<Rents> Rents = new HashSet<>(0);

    public Clients() {}

    @Column(name = "clientsId")
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }

    @Basic
    @Column(name = "Name")
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @Basic
    @Column(name = "Surname")
    public String getSurname() {
        return surname;
    }
    public void setSurname(String surname) {
        this.surname = surname;
    }
}

Klasa Cars:

package database;


import jakarta.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "Cars")

public class Cars {
    private int id;
    private String brand;
    private String model;
    private double power;
    private double price;

    @OneToMany(mappedBy = "cars")
    private Set<Rents> Rents = new HashSet<>(0);

    public Cars() {}

    @Column(name = "carsId")
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }

    @Basic
    @Column(name = "Brand")
    public String getBrand() {
        return brand;
    }
    public void setBrand(String brand) {
        this.brand = brand;
    }

    @Basic
    @Column(name = "Model")
    public String getModel() {
        return model;
    }
    public void setModel(String model) {
        this.model = model;
    }

    @Basic
    @Column(name = "Power")
    public double getPower() {
        return power;
    }
    public void setPower(double power) {
        this.power = power;
    }

    @Basic
    @Column(name = "Price")
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
}

Klasa Rents:

package database;

import jakarta.persistence.*;
import java.util.Date;

@Entity
@Table(name = "Rents")

public class Rents {

    private int id;
    private Date dateOfRent;
    private Date dateOfReturn;
    private double rentPrice;

    @ManyToOne
    @JoinColumn(name="carsId", nullable = false)
    private Cars cars;
    @ManyToOne
    @JoinColumn(name="clientsId", nullable = false)
    private Clients clients;

    public Clients getClients() {return clients;}

    public void setClients(Clients clients) {this.clients = clients;}

    public Cars getCars() {return cars;}

    public void setCars(Cars cars) {this.cars = cars;}

    public Rents() {}

    @Column(name = "Id")
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }

    @Basic
    @Column(name = "RentDate")
    public Date getDateOfRent() {
        return dateOfRent;
    }

    public void setDateOfRent(Date dateOfRent) {
        this.dateOfRent = dateOfRent;
    }

    @Basic
    @Column(name = "ReturnDate")
    public Date getDateOfReturn() {return dateOfReturn;}

    public void setDateOfReturn(Date dateOfReturn) {
        this.dateOfReturn = dateOfReturn;
    }

    @Basic
    @Column(name = "Price")
    public double getRentPrice() {
        return rentPrice;
    }

    public void setRentPrice(double rentPrice) {
        this.rentPrice = rentPrice;
    }


    @Override
    public String toString() {
        return "Rents{" +
                "id=" + id +
                ", client= " + clients.getId() +
                ", car= " + cars.getId() +
                ", dateOfRental=" + dateOfRent +
                ", dateOfReturn=" + dateOfReturn +
                '}';
    }
}

Przy projekcie korzystam z mavena, hibernate i mysql. Po wywołaniu maina:

package renting;

import database.Clients;
import org.hibernate.*;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;

public class Main {
    public static void main(String[] args) {
        final StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
        SessionFactory factory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
        Session session = factory.openSession();
        Transaction transaction = session.beginTransaction();

        Clients c1 = new Clients();
        c1.setSurname("Sainz");
        c1.setName("Carlos");

        transaction.commit();
        session.close();
        factory.close();
        System.out.println("Success");
    }
}

Dostaje następujący błąd:

Exception in thread "main" org.hibernate.type.descriptor.java.spi.JdbcTypeRecommendationException: Could not determine recommended JdbcType for `database.Cars`

Przeszukałam co mogłam, ale nie znalazłam żadnego rozwiązania, nie wiem nawet na czym może polegać błąd (to moja pierwsza styczność z tego typu projektem). Byłabym wdzięczna za naprowadzenie co mogę zmienić

1 odpowiedź

+1 głos
odpowiedź 10 grudnia 2022 przez Wiciorny Ekspert (270,170 p.)
wybrane 10 grudnia 2022 przez letmestay
 
Najlepsza
@Column(name = "carsId")
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
 
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }

tu i w każdej klasie, to powinno być związane z polem a nie z geterem. I to powinnaś poprawić w pliku, w ogóle nie wiem co się dzieje w tym kodzie i co trzeba zrobić patrząc na to, bo ten zapis : 
 

 Clients c1 = new Clients();
        c1.setSurname("Sainz");
        c1.setName("Carlos");

nic nie robi, nic się nie dzieje z obiektem c1.

Jak wygląda twój plik konfiguracyjny do bazy danych, jak tworzona jest baza danych (konfiguracja) ?

Dodatkowo każda twoja KLASA/ENCJA musi implementować EQUALS ORAZ HASHCODE, gdyż każda nowo utworzona encja nie będzie mogła być prezentowana gdyż nie ma możliwości aby   EM - wiedział że ma do czynienia z nową encją. 
Każda encja będzie traktowana jako DETACHED, a takiej encji nie możesz w ramach transakcji umieścić  do zapisu bo jest tylko READ_ONLY i operacja jest niebezpieczna  i spotkasz się z błędem : exception PersistentObjectException,

W ramach session factory ta operacja jest możliwa o ile nie wymusi na tobie EJB żebyś skorzystała z @Transactional, gdyż   używanie TransactionManagera powoduje że transakcje są AUTO_CONTROL a nie zawsze jest to możliwe żeby w tym trybie coś dodać 

komentarz 10 grudnia 2022 przez letmestay Użytkownik (520 p.)
edycja 10 grudnia 2022 przez letmestay

Dziękuje za pomoc! Poprawiłam wszędzie to przypisywanie i faktycznie wreszcie się skompilowało, baza stanęła. Co do dodawania: chciałam sobie na sztywno spróbować dodać jakiegoś klienta, żeby zobaczyć czy się doda (tak tylko do sprawdzenia) 

Jak widać zadziałało. Natomiast teraz zauważyłam, że oprócz moich tablic, stworzyly się też takie z dopiskiem _seq. Nie rozumiem skąd one się wzieły.

 w każdym _seq znajduje się tylko "next_val" w cars =1, rents = 1, clients = 51

hibernate.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/dbrents</property>
        <property name="hibernate.connection.username">login</property>
        <property name="hibernate.connection.password">haslo</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>

        <property name="hibernate.hbm2ddl.auto">update</property>
        <property name="hibernate.show_sql">true</property>
        <mapping class="database.Rents"/>
        <mapping class="database.Clients"/>
        <mapping class="database.Cars"/>

    </session-factory>

</hibernate-configuration>

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>groupId</groupId>
    <artifactId>rentalCars</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <hibernateOgmVersion>4.2.0.Final</hibernateOgmVersion>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>6.1.5.Final</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.31</version>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>2.1.214</version>
        </dependency>

    </dependencies>

</project>

*edit: dodałam do każdej klasy equals i hashcode (powinnam też generować je dla tych zmiennych które są non-null?)

komentarz 10 grudnia 2022 przez letmestay Użytkownik (520 p.)
Zamieniłam stategy = AUTO na strategy = identity i śmiga tak jak marzyłam hehe, zamykam
komentarz 10 grudnia 2022 przez Wiciorny Ekspert (270,170 p.)

Tabele seq_ tworzone są jako tabele KLUCZÓW sekwencyjnych przy generowaniu kluczy z adnotacją    @GeneratedValue(strategy = GenerationType.AUTO)

Najlepszym rozwiązaniem w tym wypadku jest zawsze podejście    @GeneratedValue(strategy = GenerationType.IDENTITY - POZWALASZ Hibernatowi na samodzielne indeksowanie nowych encji i nadawanie im ID- kluczy jednoznacznie  w kolejności  np. 1,2,3 ... itd sprawdzając już poprzednio istniejące indeksy.
 

*edit: dodałam do każdej klasy equals i hashcode (powinnam też generować je dla tych zmiennych które są non-null?)

To nadajesz dla całej ENCJI, aby stała się unikatowa- tzn Java mogła rozróżniać encje od siebie i tworzyć niezależność obiektów od siebie, jako unikatowe egzemplarze.
Powinno obejmować każde wystąpienie encji (jej element), bez znaczenia czy pole ma wartość czy nie gdyż to nie wpływa na generowanie i ostateczny wynik. Poddawane do tego są wskaźniki i referencje a nie "wartość stan" 

Dlatego że dwa różne obiekty o takich samych WŁAŚCIWOŚCIACH STANIE NIE SĄ IDENTYCZNE. 

Podobne pytania

0 głosów
1 odpowiedź 359 wizyt
pytanie zadane 30 grudnia 2017 w Java przez przemko06 Początkujący (370 p.)
0 głosów
2 odpowiedzi 1,018 wizyt
pytanie zadane 16 lutego 2021 w PHP przez XiverKi Bywalec (2,050 p.)
0 głosów
1 odpowiedź 128 wizyt
pytanie zadane 1 marca 2020 w Java przez StressedOut Nowicjusz (210 p.)

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...