Wypowiedzi
-
Ekstra, w końcu ktoś odpowiedział :) i to konkretnie.
Link się przyda na pewno, widzę że jest to co szukałem.
dziękuje za pomoc.
pzdr. -
Hej,
Zajmuję się springiem 2-3 miesiące i mam pytanie które mnie nurtuje:
Przy generowaniu widoków, np formularzy, przekazuję do widoku zmienne
@RequestMapping(value = "/admin/produkty/dodaj", method = RequestMethod.GET)
public String dodajProdukty(ModelMap model) {
Produkt produkt = new Produkt();
model.addAttribute("produkt", produkt)
.addAttribute("dataDo", produkt.getStringDataDo())
.addAttribute("dataOd", produkt.getStringDataOd())
.addAttribute("wizytowki",
wizytowkaService.pobierzWszystkieDostepne())
.addAttribute("typyKodow",
produktService.pobierzWszystkieDostepneTypy())
.addAttribute("kategorie",
kategoriaProduktowService.pobierzWszystkieDostepne())
.addAttribute("active", "dodajProdukt")
.addAttribute("nazwaTabeli", "Dodaj nowy produkt")
.addAttribute("actionZapiszForm",
"/admin/produkty/dodaj/zapisz");
return "formProdukt";
}
I teraz mam drugą metodę która obsługuję ten formularz:
@RequestMapping(value = "/admin/produkty/dodaj/zapisz", method = RequestMethod.POST)
public String zapiszProdukt(ModelMap model,
@Valid Produkt produkt, BindingResult result,
RedirectAttributes redirectAttrs) {
if (!result.hasErrors()) {
produktService.dodajAlboEdytuj(produkt);
wizytowkaService.aktualizujeStatusUsun(produkt.getWizytowka().getId());
redirectAttrs.addFlashAttribute("message", message.getMessage(
"produkt.dodanoProdukt",
new Object[] { produkt.getTytul() }, "",
Locale.getDefault()));
return "redirect:/admin/produkty";
}
model.addAttribute(
"message",
message.getMessage("bledneDaneWFormularzu", null, "",
Locale.getDefault()));
model.addAttribute("fail", 1);
model.addAttribute("produkt", produkt)
.addAttribute("dataDo", produkt.getStringDataDo())
.addAttribute("dataOd", produkt.getStringDataOd())
.addAttribute("wizytowki",
wizytowkaService.pobierzWszystkieDostepne())
.addAttribute("typyKodow",
produktService.pobierzWszystkieDostepneTypy())
.addAttribute("kategorie",
kategoriaProduktowService.pobierzWszystkieDostepne())
.addAttribute("active", "dodajProdukt")
.addAttribute("nazwaTabeli", "Dodaj nowy produkt")
.addAttribute("actionZapiszForm",
"/admin/produkty/dodaj/zapisz");
return "formProdukt";
}
I druga część kodu, czyli przekazanie zmiennych do widoku, powtarza się, a w przypadku np edycji produktu to też ten sam kod się powtórzy.
Jak powinno się pisać takie metody aby nie powtarzać kodu? -
Kontroler:
@RequestMapping(value = "/admin/artykuly", method = RequestMethod.GET)
public String pokazArtykuly(ModelMap model) {
Artykul artykul = new Artykul();
model.addAttribute("artykuly",
artykulService.pobierzWszystkieArtykuly());
model.addAttribute("artykul", artykul);
model.addAttribute("strona_id", 0);
model.addAttribute("kategorieSklepow",
kategoriaSklepyService.pobierzWszystkieDostepne());
//tutaj pobieram listę sklepów
model.addAttribute("sklepy",
sklepyService.pobierzWszystkieDostepne());
model.addAttribute("staraKategoria", 0);
model.addAttribute("textButton", "Zapisz");
model.addAttribute("actionZapiszArtykul", "/admin/artykuly/zapisz");
model.addAttribute("publikujOd", artykul.getStringPublikujOd())
.addAttribute("wyroznijArtykulDo", " ");
return "pokazArtykuly";
}
sklepyService:
@SuppressWarnings("unchecked")
@Override
public List<Sklep> pobierzWszystkieDostepne() {
Criteria crit = session.getCurrentSession().createCriteria(
Sklep.class);
crit.add(Restrictions.eq("status", true));
return crit.list();
}
Co jeszcze wkleić, jaką informację podać aby rozwikłać ten problem? Mam w ustawieniach dodane aby sesję hibernate można było używać w widoku:, czyli w web.xml:
<filter>
<display-name>OpenSessionInViewFilter</display-name>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Może tutaj leży problem? -
Dziękuję za odpowiedź, dodałem dwa tematy bo myślałem że do grupy Spring nikt nie zagląda, ostatni post był dość dawno.
Usunięcie fetch=FetchType.LAZY z OneToOne pomogło zniwelować ilość Selectów, dziękuję za wskazówkę.
Ale zastanawia mnie jedna rzecz, przy pobraniu wszystkich Sklepów i wypisaniu sysout-em Nazwy oraz Id w kontrolerze, nie powoduję wywołania dodatkowych Selectów.
A wygenerowanie listy w widoku w taki sposób:
form:select path="sklepy" multiple
items="${sklepy}" itemLabel="nazwa" itemValue="id"
generuję dodatkowe Select-y, dlaczego tak się dzieję, wiecie? -
Mam problem, mam pytanie
Mam trzy encje:
1)Artykuł
2)Sklep
3)Strona
Relację między encjami:
Jeden artykuł może mieć wiele sklepów, jeden sklep może mieć wiele artykułów.
Jeden artykuł może mieć jedną stronę.
Jeden sklep może mieć jedną stronę.
Jak to wygląda w kodzie:
Artykuł:
@OneToOne(fetch=FetchType.LAZY)
@Cascade({CascadeType.DELETE, CascadeType.DELETE_ORPHAN})
@JoinColumn(name = "strona_id")
private Strona strona;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
name="sklep_artykul",
joinColumns=@JoinColumn(name="artykul_id"),
inverseJoinColumns=@JoinColumn(name="sklep_id")
)
private Set<Sklep> sklepy = new HashSet<Sklep>();
Sklep:
@OneToOne( fetch=FetchType.LAZY)
@Cascade({CascadeType.DELETE, CascadeType.DELETE_ORPHAN})
@JoinColumn(name = "strona_id")
private Strona strona;
@ManyToMany(mappedBy="sklepy", fetch=FetchType.LAZY)
private Set<Artykul> artykuly = new HashSet<Artykul>();
Podczas dodawania artykułu udostępniam możliwość podpięcia kilku sklepów poprzez listę select multiple.
form:select path="sklepy" multiple
items="${sklepy}" itemLabel="nazwa" itemValue="id"
W kontrolerze który wywołuję widok z dodaniem artykułu dodaję initBInder aby odwzorować Stringa z formularza na listę sklepów:
@InitBinder
protected void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder) {
binder.registerCustomEditor(Set.class, "sklepy",
new CustomCollectionEditor(Set.class) {
@Override
protected Object convertElement(Object element) {
if (element != null) {
return sklepService.pobierzSklep(Integer
.parseInt(element.toString()));
}
return null;
}
});
Wszystko działa poprawnie po za jedną rzeczą.
Problem polega na tym że gdy generuję formularz z listą sklepów do wybrania, to hibernate generuję dodatkowe zbędne zapytania dla każdego sklepu, zaciągając powiązaną stronę.
W tej sytuacji potrzebuję tylko nazwę oraz id sklepu, nic więcej nie potrzebuję.
Gdy wygeneruję Select list pomijając atrybut path="sklepy" dodatkowe zapytania się nie generują.
Gdzie jest problem?Ten post został edytowany przez Autora dnia 10.03.14 o godzinie 15:43 -
Nie wiem czy w tej grupie jeszcze ktoś odpowiada bo widzę że ostatni temat był w tamtym roku, ale co mi tam, mam problem, mam pytanie
Mam trzy encje:<br />
1)Artykuł<br />
2)Sklep<br />
3)Strona<br />
Relację między encjami:
Jeden artykuł może mieć wiele sklepów, jeden sklep może mieć wiele artykułów.<br />
Jeden artykuł może mieć jedną stronę.<br />
Jeden sklep może mieć jedną stronę.<br />
Jak to wygląda w kodzie:
Artykuł:
@OneToOne(fetch=FetchType.LAZY)
@Cascade({CascadeType.DELETE, CascadeType.DELETE_ORPHAN})
@JoinColumn(name = "strona_id")
private Strona strona;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
name="sklep_artykul",
joinColumns=@JoinColumn(name="artykul_id"),
inverseJoinColumns=@JoinColumn(name="sklep_id")
)
private Set<Sklep> sklepy = new HashSet<Sklep>();
Sklep:
@OneToOne( fetch=FetchType.LAZY)
@Cascade({CascadeType.DELETE, CascadeType.DELETE_ORPHAN})
@JoinColumn(name = "strona_id")
private Strona strona;
@ManyToMany(mappedBy="sklepy", fetch=FetchType.LAZY)
private Set<Artykul> artykuly = new HashSet<Artykul>();
Podczas dodawania artykułu udostępniam możliwość podpięcia kilku sklepów poprzez listę select multiple.
form:select path="sklepy" multiple
items="${sklepy}" itemLabel="nazwa" itemValue="id"
W kontrolerze który wywołuję widok z dodaniem artykułu dodaję initBInder aby odwzorować Stringa z formularza na listę sklepów:
@InitBinder
protected void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder) {
binder.registerCustomEditor(Set.class, "sklepy",
new CustomCollectionEditor(Set.class) {
@Override
protected Object convertElement(Object element) {
if (element != null) {
return sklepService.pobierzSklep(Integer
.parseInt(element.toString()));
}
return null;
}
});
Wszystko działa poprawnie po za jedną rzeczą.
Problem polega na tym że gdy generuję formularz z listą sklepów do wybrania, to hibernate generuję dodatkowe zbędne zapytania dla każdego sklepu, zaciągając powiązaną stronę.<br />
W tej sytuacji potrzebuję tylko nazwę oraz id sklepu, nic więcej nie potrzebuję.<br />
Gdy wygeneruję Select list pomijając atrybut path="sklepy" dodatkowe zapytania się nie generują.
Gdzie jest problem?