Łączenie się z bazą danych / problem z datą w Javie i MySQL

0

Witam,
To jest mój pierwszy post tutaj więc proszę o wyrozumiałość :)
Jestem w trakcie jednego z tutoriali (kobietydokodu :( ) i mam problem z łączeniem się mojej aplikacji webowej z bazą danych.
Po 1 - kurs nie tłumaczy tak na prawdę jak to ma wszystko działać, odpalam aplikację przez intelliJ na wildfly - tu wszystko jest ok. Mam odpalony serwer MySQL (na porcie 3306 z tego co widzę). I już? Wszystko powinno działać i samo wrzucać mi dane do bazy oraz pobierać? Czy może mi to ktoś wytłumaczyć łopatologicznie?
Po 2 - jest problem z datą. W Javie korzystam z util.Date do przechowywania daty - w SQL póki co mam varchar w tym polu - myślałem że na początek tak będzie prościej, żeby tylko ruszyło... jednak wyskakuje mi błąd przy próbie dodania nowego "kota":

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.RuntimeException: java.sql.SQLException: The server time zone value '�rodkowoeuropejski czas letni' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.

Kod jest na moim koncie na githubie:
github

Z góry dzięki za pomoc!

1

Ad. 1 Jest sobie baza danych - stawiasz lokalnie jej serwer. Za pomocą driverów jdbc, możesz się do niej połączyć i wykonywać w niej zapytania (oczywiście w aplikacji javowej driver musi być w classpathie, czyli trzeba dodać dependencję za pomocą mavena). W apkach webowych pomocne są ORM-y, czyli frameworki które mapują modele javowe do encji bazodanowych (najpopularniejszym obecnie ORMem jest Hibernate) i redukują boilerplate code.

Ad. 2 No nie no, nie trzymaj daty jako varchar, to nie ma żadnego sensu. Po stronie bazy trzymaj datę w typie Timestamp, a z kolei po stronie javy unikaj przestarzałej java.util.Date i skoncentruj się na pakiecie java.time, w którym znajdziesz np. LocalDateTime.

1

Bosz, 2017 Java 8 od 3 lat a oni dalej util.Date :D
Po stronie Javy używaj albo Java 8 LocalDate albo java.sql.Date (możesz to 2 w modelu encji i później tylko konwertować :) ) W mysql też korzystaj z daty, ale najlepiej to zamień mysql na PotgreSQL.

3

Nic nie trzeba konwertować, można mieć LocalDateTime w encji.
http://www.thoughts-on-java.org/hibernate-5-date-and-time/ w hibernate 5

Przed Javą 8 używało się Joda Time i było trzeba tak:
http://blog.netgloo.com/2015/04/06/spring-boot-using-joda-time-on-jpa-entity-with-hibernate/
spring.jpa.properties.jadira.usertype.autoRegisterUserTypes = true

0

Dzięki za rady ;)
Zmieniłem typ daty w aplikacji z java.util.date na java.time.LocalDate. W bazie danych jest typ Date. Wyczytałem na kobietydokodu.pl że takie mapowanie będzie ok.
Jednak dalej wyskakuje dokładnie ten sam błąd co wcześniej...
Dodam że zależy mi na tym żeby to była sama data - bez godziny.
Póki co próbuję się połączyć przed JDBC. Mam zależność "mysql-connector-java" dodaną przez Mavena. Hibernate'm chcę zająć się później - chciałbym najpierw ogarnąć łączenie za pomocą JDBC :)

0
domrycz napisał(a):

Dodam że zależy mi na tym żeby to była sama data - bez godziny.

Proponuję trzymać samą datę po stronie javy (czyli LocalDate zamiast LocalDateTime) natomiast na bazie konsekwentnie trzymać Timestampa - z godziną 12:00 A.M czyli północ. Znowu jest odwieczny problem ze strefami czasowymi - załóżmy że np koleś z Indii dodał np usera u siebie o 6 rano w czwartek. Będzie on załóżmy współdzielić dane z kolegą z Kaliforni, który korzysta z tego samego serwera, będzie u niego załóżmy popołudnie środa i zobaczy użytkownika z przyszłości xd Także wtedy mogłoby się wydawać, żeby sensownym by było trzymanie daty serwera a nie klienta. No cóż, wtedy jeśli np serwer byłby w Kaliforni a Hindus dodałby użytkownika z rana, to potem zobaczy że usera ma jednak z wczoraj :/ No z tym jest pełno pier****lenia jeśli chcemy napisać dobrze xd

A wyższa szkoła jazdy to wtedy jak np uwzględnimy, że w Polsce i np Australii są zmiany czasu na zimowy i letni, i do tego te zmiany nie zachodzą w tym samym momencie :D

0

Ale po co timestamp po stronei bazy? Jak nie jest potrzeba godzina to wystarczy zwykła data

0

Panowie generalnie to pal licho to czy się ten Hindus dogada z gościem z Kalifornii - ja chcę żeby to po prostu zadziałało ;)
Sprawa wygląda tak że bez względu czy mam zwykłe DATE czy TIMESTAMP po stronie bazy to i tak wywala błąd i to nie działa... Jak to zrobić żeby dzięki aplikacji wreszcie wrzucić coś do bazy?

Edit:
Co do daty udało mi się rozwiązać problem! Dodałem w beanie DataSource:

"jdbc:mysql://localhost:3306/cats?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC" 

Jednak teraz wyskakuje kolejny błąd gdy chcę dodać coś do bazy:

Context Path:/Cats-webapp-1.0-SNAPSHOT
Servlet Path:/add
Path Info:null
Query String:null
Stack Trace
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException

0

Kod jest na moim koncie na githubie:
github

Chyba nie zrobiłeś pusha.

0

Faktycznie.. tak się podnieciłem tym, że udało mi się ogarnąć tą datę, że zapomniałem o pushu.
Teraz w Development jest już aktualna wersja.

0

Musisz się dorwać do logu i tam zlokalizować źródło NPE. Nie da się diagnozować takich błędów bez stacktrejsa. Powodzenia :)

0

To może na razie wywal tą datę, zobacz czy Ci aplikacja działa, czy zapisuję do bazy, itd. Jak już zabangla, to weźmiesz się za datę.

0

Stack Trace:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:805)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)

Czy to o to chodziło? Mi to zupełnie nic nie mówi :) Ale nie widzę, żeby było tutaj coś o dacie - wcześniej było ale udało mi się problem rozwiązać.

0

Wszystko czego potrzeba by pozbyć się problemu z serverTimezone

String url = "jdbc//localhost:3306/db?serverTimezone=" + TimeZone.getDefault().getID()

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