Visualizzazione dei risultati da 1 a 8 su 8
  1. #1

    [Java] Accedere alla lista di Prodotti di Fornitori tramite thymeleaf

    Buongiorno, Ho le due entità:

    codice:
       @Entity
     @Table(name = "fornitori")
     publicclass Fornitore {
     
     @Id
     @Column(name = "id")
     @GeneratedValue (strategy = GenerationType.AUTO)
     private Long id;
    
     
     @Column(name = "descrizione")
     private String descrizione;
     
     @OneToMany(fetch = FetchType.LAZY, mappedBy="fornitore")
     private List<Prodotto> prodotti;
      public String getDescrizione() {
     returndescrizione;
         }
      publicvoid setDescrizione(String descrizione) {
     this.descrizione = descrizione;
         }
      public List<Prodotto> getProdotti() {
     returnprodotti;
         }
      publicvoid setProdotti(List<Prodotto> prodotti) {
     this.prodotti = prodotti;
         }
     
         Fornitore() {
     
         }
     
     public Fornitore(String descrizione, List<Prodotto> prodotti) {
     
     this.descrizione = descrizione;
     this.prodotti = prodotti;
     
         }
    
      }
    
    
    
       @Entity
     @Table(name = "prodotti")
     publicclass Prodotto {
     
     @Id
     @GeneratedValue (strategy = GenerationType.AUTO)
     private Long id;
     
     //@GeneratedValue (strategy = GenerationType.IDENTITY)
     @Column(name = "codice")
     private String codice;
     
     @Column(name = "descrizione")
     private String descrizione;
     
     
     @Temporal(TemporalType.DATE)
     //@DateTimeFormat(pattern = "DD-MM-YYYY")
     @Column(name = "datacreazione")
     private Date datacreazione;
     
     @Column
     private Integer prezzo;
     
     @OneToOne
     @JoinColumn(name = "sconto_id", referencedColumnName = "id")
     private Sconto sconto;
     
     @ManyToOne(fetch = FetchType.LAZY)
     @JoinColumn(name = "fornitore_id", referencedColumnName = "id")
     private Fornitore fornitore;
     
     public Integer getPrezzo() {
     returnprezzo;
         }
       publicvoid setPrezzo(Integer prezzo) {
     this.prezzo = prezzo;
         }
       public String getCodice() {
     returncodice;
         }
       publicvoid setCodice(String codice) {
     this.codice = codice;
         }
       public String getDescrizione() {
     returndescrizione;
         }
       publicvoid setDescrizione(String descrizione) {
     this.descrizione = descrizione;
         }
       public Date getDatacreazione() {
     returndatacreazione;
         }
       publicvoid setDatacreazione(Date datacreazione) {
     this.datacreazione = datacreazione;
         }
       public Prodotto() {
     
         }
     
     public Prodotto(intprezzo, String descrizione) {
     //this.codice = codice;
     this.prezzo = prezzo;
     this.descrizione = descrizione;
         }
       
     
     }
    
     
     
    Nel file home.html:
    
     
    
    
      <tr th:each="fornitore : ${listFornitori}">
    
                         <td th:text=${fornitore.descrizione}></td></tr>
    
    Come accedo alla lista di prodotti?
                                                                            
    
                     
    
    
    jabjoint

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,255
    Quote Originariamente inviata da jabjoint Visualizza il messaggio
    Come accedo alla lista di prodotti?
    Il punto è che la lista dei prodotti ha il FetchType.LAZY. Pertanto puoi accedere alla lista solo nell'arco di tempo in cui il persistence context è attivo.
    Se hai fatto un service con un metodo con @Transactional(readOnly=true) per leggere i fornitori, il persistence context è attivo solo lì dentro. Se l'accesso alla lista dei prodotti è fatto SOLO ad un livello più alto (controller/vista), il ORM non applica la lettura in modo lazy perché sei fuori dal persistence context.

    La soluzione banale: fai un get della lista nel metodo del service, questo fa attivare il meccanismo lazy della lettura.

    Un'altra soluzione più architetturale è quella di NON esporre mai gli oggetti delle entity al controller/vista ma fornire degli oggetto DTO di passaggio che sono eventualmente più focalizzati sul modello della vista.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  3. #3
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Il punto è che la lista dei prodotti ha il FetchType.LAZY. Pertanto puoi accedere alla lista solo nell'arco di tempo in cui il persistence context è attivo.
    Se hai fatto un service con un metodo con @Transactional(readOnly=true) per leggere i fornitori, il persistence context è attivo solo lì dentro. Se l'accesso alla lista dei prodotti è fatto SOLO ad un livello più alto (controller/vista), il ORM non applica la lettura in modo lazy perché sei fuori dal persistence context.

    La soluzione banale: fai un get della lista nel metodo del service, questo fa attivare il meccanismo lazy della lettura.

    Un'altra soluzione più architetturale è quella di NON esporre mai gli oggetti delle entity al controller/vista ma fornire degli oggetto DTO di passaggio che sono eventualmente più focalizzati sul modello della vista.

    Non capisco perché non viene create la tabella prodotti in fornitori...:

    codice:
      
    mysql> select * from fornitori;
    +----+-------------+
    | id | descrizione|
    +----+-------------+
    |  1 | FornitoreX  |
    |  2 | FornitoreX  |
    |  3 | FornitoreX  |
    |  4 | FornitoreX  |
    |  5 | FornitoreX  |
    +----+-------------+
    5 rows in set (0,00 sec)
    
    
    
    
    jabjoint

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,272
    Eh?
    Ti aspetti di trovare una tabella dentro ad una tabella?
    Data la relazione ONE-TO-MANY, semmai troverai un campo "fornitore" dentro alla tabella Prodotto che referenzia il singolo record della tabella Fornitore...
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,255
    Quote Originariamente inviata da jabjoint Visualizza il messaggio
    Non capisco perché non viene create la tabella prodotti in fornitori...:
    Hai due tabelle, fornitori e prodotti. La foreign key sta in prodotti, ovvero ciascun prodotto ha il Id di riferimento al fornitore. Non il contrario (o altro).
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  6. #6
    Si il campo, non la tabella, Il fatto che nemmeno in prodotti vedo il campo fornitori.

    Ad ogni modo (non so se sbaglio) mi aspettavo di infilare i prodotti cosi'(riporto il controller):

    codice:
     @RequestMapping("/")
     public String homePage(Model model) {
     
     model.addAttribute("listFornitori", fornitoreService.getAllFornitori());
    
     
     return"home";
     
         }
     
     @RequestMapping("/saveFornitore")
     @ResponseBody
     public String saveFornitori(Model model) {
     
             List<Prodotto> prodotti = new ArrayList<Prodotto>();
     prodotti.add(new Prodotto(130,"TV 1"));
     prodotti.add(new Prodotto(230,"TV 2"));
     
             Fornitore fornitore = new Fornitore("FornitoreX", prodotti);
     fornitoreService.saveFornitore(fornitore);
      return"saved"; 
         }
     
     @RequestMapping("/getProdotti")
     public String getFornitori(Model model) {        
    //provo a prelevare i prodotti del primo fornitore
    
     
     model.addAttribute("listProdotti", fornitoreService.getAllProdotti(Long.valueOf(1)));                              
    
      return"prodotti";        
         }
    



    NON funziona...

    Io devo poter prelevare i prodotti di ciascun fornitore...

    Se l'approccio è totalmente sbagliato come mi fate capire:
    Cioè dovrei creare il repository di prodotti?
    Ultima modifica di jabjoint; 19-01-2023 a 15:05
    jabjoint

  7. #7
    Il punto è che la lista dei prodotti ha il FetchType.LAZY. Pertanto puoi accedere alla lista solo nell'arco di tempo in cui il persistence context è attivo.
    Se hai fatto un service con un metodo con @Transactional(readOnly=true) per leggere i fornitori, il persistence context è attivo solo lì dentro. Se l'accesso alla lista dei prodotti è fatto SOLO ad un livello più alto (controller/vista), il ORM non applica la lettura in modo lazy perché sei fuori dal persistence context.

    La soluzione banale: fai un get della lista nel metodo del service, questo fa attivare il meccanismo lazy della lettura.

    Un'altra soluzione più architetturale è quella di NON esporre mai gli oggetti delle entity al controller/vista ma fornire degli oggetto DTO di passaggio che sono eventualmente più focalizzati sul modello della vista.
    ]
    Si penso sia questo il punto. Infatti alla prima creazione della tabella, i prodotti relativi al fornitore con l'ID=1, vengono rilevati
    Ma non capisco come risolvere...

    Non ho usato l'annotazione @Transactional, ho aggiunto questo(ma come dicevo funziona solo quando il db è appena rigenerato):

    codice:
      @Override
    
     public List<Prodotto> getAllProdotti(Long id) {	
    
     
     return getFornitoreById(id).getProdotti();
    
     
     	}
    



    Ultima modifica di jabjoint; 19-01-2023 a 16:16
    jabjoint

  8. #8
    Quote Originariamente inviata da LeleFT Visualizza il messaggio
    Eh?
    Ti aspetti di trovare una tabella dentro ad una tabella?
    Data la relazione ONE-TO-MANY, semmai troverai un campo "fornitore" dentro alla tabella Prodotto che referenzia il singolo record della tabella Fornitore...
    mysql> describe prodotti;
    +---------------+--------------+------+-----+---------+----------------+
    | Field | Type | Null | Key | Default | Extra |
    +---------------+--------------+------+-----+---------+----------------+
    | id | int | NO | PRI | NULL | auto_increment |
    | codice | varchar(255) | YES | | NULL | |
    | datacreazione | date | YES | | NULL | |
    | descrizione | varchar(255) | YES | | NULL | |
    | prezzo | int | YES | | NULL | |
    | fornitore_id | int | YES | MUL | NULL | |
    | sconto_id | int | YES | MUL | NULL | |
    +---------------+--------------+------+-----+---------+----------------+

    Tutto ok, allora!
    jabjoint

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2023 vBulletin Solutions, Inc. All rights reserved.