Otrzymuję następujący błąd podczas używania prymitywnego atrybutu w moim obiekcie domeny Grails:
Null value was assigned to a property of primitive type setter of MyDomain.myAttribute
org.hibernate.PropertyAccessException: Null value was assigned to a property of primitive type setter of MyDomain.myAttribute
at grails.orm.HibernateCriteriaBuilder.invokeMethod(HibernateCriteriaBuilder.java:1077)
Odpowiedzi:
Zgodnie z tym wątkiem SO , rozwiązaniem jest użycie nieprymitywnych typów opakowań; np.
Integer
zamiastint
.źródło
Wartość null nie może być przypisana do typu pierwotnego, takiego jak int, long, boolean itp. Jeśli kolumna bazy danych odpowiadająca polu w twoim obiekcie może mieć wartość null, to twoje pole powinno być klasą opakowania, taką jak Integer, Long, Boolean itp.
Niebezpieczeństwo polega na tym, że Twój kod będzie działał poprawnie, jeśli w bazie danych nie będzie żadnych wartości null, ale zakończy się niepowodzeniem po wstawieniu wartości null.
Zawsze możesz zwrócić typ pierwotny z metody pobierającej. Dawny:
Ale w większości przypadków będziesz chciał zwrócić klasę opakowania.
Więc albo ustaw kolumnę DB, aby nie zezwalała na wartości null, albo użyj klasy opakowania.
źródło
Typ pierwotny nie może mieć wartości null. Rozwiązaniem jest więc zastąpienie typu pierwotnego pierwotną klasą opakowania w pliku tableName.java. Jak na przykład:
odnośnik http://en.wikipedia.org/wiki/Primitive_wrapper_class, aby znaleźć klasę opakowania typu pierwotnego.
źródło
Postaram się, abyś zrozumiał na przykładzie. Załóżmy, że masz tabelę relacyjną (STUDENT) z dwiema kolumnami oraz ID (int) i NAME (String). Teraz, jako ORM, utworzyłbyś klasę encji mniej więcej następującą: -
Załóżmy, że tabela zawiera już wpisy. Teraz, jeśli ktoś poprosi Cię o dodanie kolejnej kolumny „AGE” (liczba całkowita)
Będziesz musiał ustawić wartości domyślne na NULL, aby dodać kolejną kolumnę do wstępnie wypełnionej tabeli. To sprawia, że dodajesz kolejne pole w klasie. Teraz pojawia się pytanie, czy do deklarowania pola będziesz używać pierwotnego typu danych, czy nieprymitywnego typu opakowującego danych.
lub
będziesz musiał zadeklarować pole jako niepymitywny opakowujący typ danych, ponieważ kontener będzie próbował zamapować tabelę na jednostkę. W związku z tym nie byłby w stanie odwzorować wartości NULL (domyślnie), gdybyś nie zadeklarował pola jako opakowania i ostatecznie wyrzuciłby komunikat „Wartość Null została przypisana do właściwości ustawiającej typ pierwotny” Wyjątek.
źródło
użyj Integer jako typu i odpowiednio podaj setter / getter.
źródło
Nie używaj prymitywów w swoich klasach Entity , zamiast tego używaj ich odpowiednich opakowań. To rozwiąże ten problem.
Poza klasami Entity możesz użyć walidacji! = Null dla pozostałej części przepływu kodu.
źródło
Albo całkowicie unikaj
null
w DB przezNOT NULL
i w jednostce Hibernate@Column(nullable = false)
odpowiednio za pośrednictwem lub użyjLong
wrappera zamiast swoichlong
prymitywów.Prymityw nie jest przedmiotem, dlatego nie możesz go przypisać
null
.źródło
Są dwa sposoby
null
private int var;
można zainicjować jakoprivate Integer var;
źródło
@Dinh Nhat, twoja metoda ustawiająca wygląda nieprawidłowo, ponieważ ponownie wstawiłeś tam typ prymitywny i powinno to być:
źródło
Zmień typ parametru z prymitywnego na Object i wprowadź zerową kontrolę w metodzie ustawiającej. Zobacz przykład poniżej
źródło
Zmień na
źródło
Upewnij się, że pole myAttribute bazy danych zawiera wartość null zamiast zera.
źródło