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

Asocjacja pomiędzy klasami, niezgodność typów - JDBC

0 głosów
612 wizyt
pytanie zadane 30 marca 2016 w Java przez jocom Początkujący (390 p.)
edycja 30 marca 2016 przez jocom

Dobry wieczór wszystkim,

kontynuuję nauką JDBC i doszedłem do momentu gdzie mam następującą sytuacje.

Mam dwie tabele adres i autor. Tabela autor jest połączona z tabelą adres za pomocą klucza obcego adres_id w tabeli autor. Chcę wykonać INSERT do tabeli autor za pomocą metody jak poniżej:

Metoda utworz

public Autor utworz(Autor autor) {

		try {
			Connection polaczenie = PolaczenieDoBazyDanych.utworzPolaczenie();
			try {
				PreparedStatement utworzRekord = polaczenie.prepareStatement(
						"INSERT INTO autor(imie, nazwisko, data_urodzenia, adres_id ) VALUES(?,?,?,?)",
						PreparedStatement.RETURN_GENERATED_KEYS);
				utworzRekord.setString(1, autor.getImie());
				utworzRekord.setString(2, autor.getNazwisko());
				utworzRekord.setDate(3, (java.sql.Date) autor.getDataUrodzenia());// nie rozumiem dlaczego musiałem zrobić to rzutowanie?
				utworzRekord.setInt(4, autor.getAdresId());// błąd The method setInt(int, int) in the type PreparedStatement is not applicable for the arguments (int, Adres)
				int zmienWiersz = utworzRekord.executeUpdate();

				ResultSet resultSet = utworzRekord.getGeneratedKeys();

				while (resultSet.next()) {
					Integer adresId = resultSet.getInt(1);
					autor.setAutorId(adresId);
				}

				return autor;

			} finally {
				polaczenie.close();
			}

		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;

i pojawia się problem. Chcę w poleceniu INSERT podać adres_id krotki z tabeli adres który będzie odpowiadał odpowiedniemu autorowi z tabeli autor. W klasie Autor zastosowałem asocjację jednokierunkową z klasą Adres za pomocą "private Adres adresId;"

Klasa Autor

package com.jdbctest.domeny;

import java.util.Date;

public class Autor {

	private Integer autorId;
	private String imie;
	private String nazwisko;
	private Date dataUrodzenia;
	private Adres adresId;
	
	public Integer getAutorId() {
		return autorId;
	}
	public void setAutorId(Integer autorId) {
		this.autorId = autorId;
	}
	public String getImie() {
		return imie;
	}
	public void setImie(String imie) {
		this.imie = imie;
	}
	public String getNazwisko() {
		return nazwisko;
	}
	public void setNazwisko(String nazwisko) {
		this.nazwisko = nazwisko;
	}
	public Date getDataUrodzenia() {
		return dataUrodzenia;
	}
	public void setDataUrodzenia(Date dataUrodzenia) {
		this.dataUrodzenia = dataUrodzenia;
	}
	public Adres getAdresId() {
		return adresId;
	}
	public void setAdresId(Adres adresId) {
		this.adresId = adresId;
	}
}

Pole adresId w klasie Adres jest typu Integer "private Integer adresId;"

Klasa Adres

package com.jdbctest.domeny;

public class Adres {
	
	private Integer adresId;
	private String ulica;
	private String miejscowosc;
	private String kodPocztowy;
	
	public Adres() {
	}


	public Adres(String ulica, String miejscowosc, String kodPocztowy) {
		this.ulica = ulica;
		this.miejscowosc = miejscowosc;
		this.kodPocztowy = kodPocztowy;
	}
	
	@Override
	public String toString() {
		return "Adres [adresId=" + adresId + ", ulica=" + ulica + ", miejscowosc=" + miejscowosc + ", kodPocztowy="
				+ kodPocztowy + "]";
	}


	public Integer getAdresId() {
		return adresId;
	}
	public void setAdresId(Integer adresId) {
		this.adresId = adresId;
	}
	public String getUlica() {
		return ulica;
	}
	public void setUlica(String ulica) {
		this.ulica = ulica;
	}
	public String getMiejscowosc() {
		return miejscowosc;
	}
	public void setMiejscowosc(String miejscowosc) {
		this.miejscowosc = miejscowosc;
	}
	public String getKodPocztowy() {
		return kodPocztowy;
	}
	public void setKodPocztowy(String kodPocztowy) {
		this.kodPocztowy = kodPocztowy;
	}

}

Mimo to podczas pisania metody utworz pojawia mi się błąd w miejscu "utworzRekord.setInt(4,autor.getAdresId());", w którym chcę uzupełnić odpowiednią wartość w poleceniu INSERT dla adresId. Błąd o treści "The method setInt(int, int) in the type PreparedStatement is not applicable for the arguments (int, Adres)" jest jasny rozumiem że nie mogę w setInt podać indexu wartości w poleceniu INSERT i wartości adresId typu Autor, ale nie wiem jak w takim razie mam podać wartość adresId do polecenia INSERT?

Z góry dziękuję wszystkim za udzieloną pomoc i krytykę.  

1 odpowiedź

0 głosów
odpowiedź 30 marca 2016 przez mbabane Szeryf (79,260 p.)
wybrane 8 czerwca 2016 przez jocom
 
Najlepsza

polecenie do bazy to ciag znakow wiec trzeba wszystko po zamieniac na String

Troche dziwne ze do pola adresID musisz uzyc az klasy Integer a nie zwyklego int'a, obiekty typu Integer maja jedna wazna ceche są niezmienialne. A stosujac obiekt Integer tak:

 public void setAdresId(Integer adresId) {

        this.adresId = adresId;
}

pole adresId nie bedzie miec wartosci z podanego parametru a jedynie jego referencje. I stosowanie tego typu do takiego celu nie jest konieczne, a wrecz rażące w oczy.

I podobnie jest w metodzie ktora ma rzekomo zwracac wartosc z tego pola tzn. metoda getAdresId().

Ok jesli nie chcesz zbyt ingerowac w ten kod i zrobic zeby dzialalo to wystarczy zrobic zeby obiekt typu Integer oddal nam zwyklego int'a:

utworzRekord.setInt(4, autor.getAdresId().intValue() );

aczkolwiek strasznie sobie komplikujesz

 

komentarz 30 marca 2016 przez jocom Początkujący (390 p.)

Dziękuję za odpowiedź.

Troche dziwne ze do pola adresID musisz uzyc az klasy Integer a nie zwyklego int'a, obiekty typu Integer maja jedna wazna ceche są niezmienialne

Na początek wytłumaczę dlaczego użyłem Integer zamiast int. Zamysłem takiego posunięcia z mojej strony jest reprezentacją int i Integer w bazie danych np po wykonaniu polecenia INSERT. Jeżeli zdarzyłoby mi się kiedyś wykonać INSERT pomijając wartość dla kolumny typu INT w bazie danych to INSERT typu int wpisze tam swoją wartość domyślną typu int czyli 0 co nie zawsze może być pożądanym wynikiem. INSERT wartości typu Integer wstawi do bazy danych wartość domyślną dla typu Integer czyli null. Tyle na dzisiaj wynika z mojej wiedzy w tym temacie. Popraw mnie jeżeli to głupoty.

Ok jesli nie chcesz zbyt ingerowac w ten kod i zrobic zeby dzialalo to wystarczy zrobic zeby obiekt typu Integer oddal nam zwyklego int'a:

?

1

utworzRekord.setInt(4, autor.getAdresId().intValue() );

aczkolwiek strasznie sobie komplikujesz

Możesz mi proszę napisać jak Ty byś to rozwiązał? Chodzi mi o INSERT i wartość w kolumnie adresId. Nie robiłbyś asocjacji pomiędzy klasami? Z góry dziękuję za odpowiedź.

    

 

komentarz 30 marca 2016 przez jocom Początkujący (390 p.)

utworzRekord.setInt(4, autor.getAdresId().intValue() );

Nie mogę bezpośrednio zastosować intValue() na autor.getAdresId() z powodu błędu "The method intValue() is undefined for the type Adres".

komentarz 30 marca 2016 przez mbabane Szeryf (79,260 p.)
edycja 31 marca 2016 przez mbabane

przepraszam moje niedopatrzenie.

Sprobuj w taki sposob:

utworzRekord.setInt(4, autor.getAdresId().getAdresId().intValue() );

Zawsze mozna robic (wrecz wydaje mi sie ze powinno sie robic zeby bylo porzednie) odpowienia walidacje danych, np. czy wszystkie pola zostaly wypelnione.

komentarz 31 marca 2016 przez jocom Początkujący (390 p.)

Dziękuję,

twój sposób pomógł mi wyeliminować problem "The method setInt(int, int) in the type PreparedStatement is not applicable for the arguments (int, Adres)" .

utworzRekord.setInt(4, autor.getAdresId().getAdresId().intValue() ); 

Żeby wykonać INSERT utworzyłem konstruktor z trzema argumentami. Jednym z nich jest pole adresId typu Adres. 

	public Autor(String imie, String nazwisko, Adres adresId) {
		super();
		this.imie = imie;
		this.nazwisko = nazwisko;
		this.adresId = adresId;
	}

 Kiedy tworzę nowy obiekt typu Autor i ustawiam pola konstruktora 

case 4:
	// INSERT Autor
	Autor autor = new Autor("Stefan", "Kowalski", 2 ); 
	autor = adresDB.utworz(autor);
	System.out.println("dodano nowy rekord do Autor");
	break;

pojawia się błąd "The constructor Autor(String, String, int) is undefined". Błąd jak sądzę jest spowodowany tym że konstruktor posiada pola (String, String, Autor) ale jak w takim przypadku mam zdefiniować adresId który chcę wpisać do tabeli Autor?

Dziękuję za pomoc.

komentarz 31 marca 2016 przez mbabane Szeryf (79,260 p.)
edycja 31 marca 2016 przez mbabane

Błąd jak sądzę jest spowodowany tym że konstruktor posiada pola (String, String, Autor)

Dokladnie tak! A Ty robiac to tak: new Autor("Stefan", "Kowalski", 2 ); podajesz jako ostatni parametr, ktory chcesz zeby byl typu Adres, prosty typ int.

Typ Autor to klasa, a jak tworzymy i zapisujemy dane do obiektow?
np. jesli mamy konstruktor, ktory pobiera potrzebne dane robimy to w ten sposob: 
new NazwaKlasy(paramDoKonstr1, paramDoKonstr2, ...);

Tak?

Wiec trzeba tez tak zrobic:

Autor autor = new Autor("Stefan", "Kowalski", new Adres("ulica", "miejscowosc", "22-222") );

Ewentualnie wczesniej, tj. przed tworzeniem obiektu autor, przygotować sobie odpowiedni obiekt o typie Adres.

 

Aj i jeszce jedno niedopatrzenie, pole takie jak np.: Integer autorId nie powinno byc podawane przez kod porogramu, za to pole powinna byc odpowiedzialna baza danych, dzieki temu uniknie sie problemu z generowaniem odpowiedniej wartosci dla tego pola (to pole pewnie jest w tabeli kluczem glownym i w zasadzie nie ma znaczenia jaka to bedzie wartosc, byleby byla unikatowa wzgledem tabeli), dlatego za to powinna odpowiadac sama baza danych, jesli jest to baza Oracle to trzeba robic sekwencje, jesli np. MySQL to trzeba ustawic zeby takie pole bylo autoinkrementowane.

Podobne pytania

0 głosów
4 odpowiedzi 391 wizyt
pytanie zadane 4 października 2018 w C i C++ przez estewui Początkujący (270 p.)
0 głosów
2 odpowiedzi 472 wizyt
0 głosów
1 odpowiedź 424 wizyt
pytanie zadane 5 stycznia 2018 w Java przez barteku12 Obywatel (1,340 p.)

93,631 zapytań

142,553 odpowiedzi

323,056 komentarzy

63,139 pasjonatów

Advent of Code 2025

Top 15 użytkowników

  1. 2900p. - dia-Chann
  2. 2870p. - DziarnowskiJ
  3. 2827p. - Łukasz Piwowar
  4. 2783p. - raydeal
  5. 2758p. - Adrian Wieprzkowicz
  6. 2713p. - rucin93
  7. 2579p. - Łukasz Eckert
  8. 2459p. - CC PL
  9. 2184p. - Maurycy W
  10. 2082p. - Michal Drewniak
  11. 1885p. - robwarsz
  12. 1811p. - rafalszastok
  13. 1600p. - Rafał Trójniak
  14. 1588p. - Tomasz Bielak
  15. 1494p. - ssynowiec
Szczegóły i pełne wyniki

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

Kursy INF.02 i INF.03
...