hibernate kilka pytań nowicjuszki

0

Hej. Bawię się troche hibernate, mam takie encje:

@Entity
@Table(name = "clients")
public class Client implements Serializable {

//    @Temporal(TemporalType.TIMESTAMP)
//    @Column(name = "last_update", nullable = false)
//    private Date lastUpdate;
//
//    @Temporal(TemporalType.TIMESTAMP)
//    @Column(name = "created", nullable = false)
//    private Date created;
//
//    @PrePersist
//    protected void onCreate() {
//        created = lastUpdate = new Date();
//    }
//
//    @PreUpdate
//    protected void onUpdate() {
//        lastUpdate = new Date();
//    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "client_id", unique = true)
    private Long id;

    @Column(name = "name", nullable = false)
    private String name;

    @ManyToMany(cascade = CascadeType.ALL, mappedBy = "clients")
    private Set<Product> products = new HashSet<>();

    public Set<Product> getProducts() {
        return products;
    }
@Entity
@Table(name = "products")
public class Product implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "product_id", unique = true)
    private Long id;

    @Column(name = "name", nullable = false, unique = false)
    private String name;

    @Column(name = "price", nullable = false)
    private Integer price;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(
            name = "products_to_clients",
            joinColumns = {@JoinColumn(
                    name = "product_id",
                    referencedColumnName = "product_id")},
            inverseJoinColumns = {@JoinColumn(
                    name = "client_id",
                    referencedColumnName = "client_id")}
    )
    private Set<Client> clients = new HashSet<>();

    public Set<Client> getClients() {
        return clients;
    }

gettery, settery itd... pomijam. Mam do tego standardowe dao i taki test:

    //TODO: dlaczego nie zapisuje relacji ?
    @Test
    public void shouldFindAllProductsByClientNIEZAPISUJERELACJI() {
        //given
        Client client1 = helper.createRndClient();
        Client client2 = helper.createRndClient();
        client1.getProducts().add(helper.createRndProduct());
        client2.getProducts().add(helper.createRndProduct());
        client2.getProducts().add(helper.createRndProduct());
        clientDao.save(client1);
        clientDao.save(client2);

        //when
        List<Product> productsC1 = productDao.findAllProductsByClient(client1);
        List<Product> productsC2 = productDao.findAllProductsByClient(client2);

        //then
        Assert.assertEquals(1, productsC1.size());
        Assert.assertEquals(2, productsC2.size());
    }

    //a takie cos zapisuje wszystko lacznie z relacjami
    @Test
    public void shouldFindAllProductsByClient() {
        //given
        Client client1 = helper.createRndClient();
        Client client2 = helper.createRndClient();

        Product product1 = helper.createRndProduct();
        Product product2 = helper.createRndProduct();
        Product product3 = helper.createRndProduct();

        product1.getClients().add(client1);
        product2.getClients().add(client2);
        product3.getClients().add(client2);

        productDao.save(product1);
        productDao.save(product2);
        productDao.save(product3);


        //when
        List<Product> productsC1 = productDao.findAllProductsByClient(client1);
        List<Product> productsC2 = productDao.findAllProductsByClient(client2);

        //then
        Assert.assertEquals(1, productsC1.size());
        Assert.assertEquals(2, productsC2.size());
    }

Moje pytania:

  1. Da się jakoś zmusić hibernate, aby zajmował się datami created i update? Tamten zakomentowany sposób nie działa (czytałam o tym,
    w necie, że te adnotacje JPA, działają jak używam jpa i hibernate jako odstawce a tak nie robię).
    Czy zostają mi tylko jakieś EJB listenery, invokery i wgl?

  2. Dlaczego przy pierwszym teście nie zapisuje mi relacji do tabelki products_to_clients (resztę zapisuje okey) a przy drugim zapisuje
    wszystko oke?

  3. Z doświadczenia polecacie przekazywanie do dao obiektu czy id obiektu?
    chodzi mi np. o takie metody w ClientDao:

    List<Client> findAllClientsByProduct(Product product);
    //vs
    List<Client> findAllClientsByProduct(Integer productId);
1
  1. Nie zapisuje ci relacji poniewaz tak skonfigurowalas twoje mapowanie - w Client masz ze products jest mappedBy Product#clients. Co to oznacza - ze relacje sa zarzadzane przez Product. W Client nawet nie ma definicji jak taka relacja mialaby zostac zapisana, dopiero Product ma taka wiedze. Jak zapisujesz zatem obiekty Client to hibernate mysli sobie: 'relacja do products jest zarzadzana przez Product, wiec olewam to pole i nie robie nic'). Jak zapisujesz obiekty Product, hibernate mysli sobie: 'ok, Product zarzadza relacja, wiec musze sie troche wysilic - musze zapisac dodatkowo wszystkich Client (kaskadowanie) oraz relacje do nich').

  2. To co przekazujesz zalezy od ciebie i przypadku. Np. jak chcesz wyszykac czegos po id to nie masz wyboru bo jeszcze nie masz obiektu. Jak chcesz cos zapisac to raczej musisz podac obiekt z danymi a nie samo id.

0

Okey rozumiem. Odnośnie 3 pytania myślałam, że to może jakoś na wydajność wpływać przekazywanie całych obiektów jako argumenty a Integer id. (tak przynajmniej w C chyba było zamiast całych struktur przekazywać wskaźnik do struktury). No i do tego dochodzi kontrola typu albo kwestia np. Integer vs prymityw int. dobra zostaje pierwsze pytanko a potem będę mieć jeszcze kilka odnośnie restrykcji (ale to na inny temat)

1

@karolinaa w javie wszystko jest przekazywane przez referencje/wskaźnik, tylko że tego nie widać bo nie ma żadnych gwiazdek ani ampersandów. Tylko typy prymitywne są kopiowane jako argumenty metod.

0

Zgadza sie to co napisal ktos w komentarzach, w Javie wszystko przekazywane jest przez kopiowanie. Tyle tylko, ze kopiowane sa referencje na obiekty lub prymitywy, czyli max pare bajtow na parametr).
W C/C++ jest podobnie, jak funckcja wyglada tak: foo(Costam *a) - kopiowany jest wskaznik, i podstawienie czegos pod a w ciele funkcji nie zmienia wskaznika poza funkcja, bo zmienia sie jego kopia. Tak jak napisal shalom, trzeba wskaznika na wskaznik itp.

1 użytkowników online, w tym zalogowanych: 0, gości: 1