Cześć,
Niedawno przerobiłem kurs tworzenia aplikacji webowych w javie, teraz próbuję zrobić swoją pierwszą apke, ale utknąłem w następującym punkcie:
- Chce zrobić dodawanie do DB, przy pomocy formularza napisanego w Js w pliku index.html
- Niestety dostaję cały czas błąd informujący, że jeden z parametrów jest NULL (w db jest pole not null), ale nie rozumiem dlaczego, bo formularz czyta wartość pola i np. potrafi wyświetlić wpisaną treść przy pomocy: alert(tresc z labela)
- DOSTAJĘ NASTĘPUJĄCY BŁĄD:
WARN: SQL Error: 23502, SQLState: 23502
maj 06, 2021 11:04:58 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Pole nie może być NULL"NAZWA"
NULL not allowed for column "NAZWA"; SQL statement:
insert into MAGAZYN_SUROWCOW (ilosc, nazwa, typ, id) values (?, ?, ?, ?) [23502-200]
[qtp95395916-23] WARN org.eclipse.jetty.server.HttpChannel - /magazyn
javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1364)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:451)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3210)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2378)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:447)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:40)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101)
at io.github.mat3e.MagazynRepository.addMagazyn(MagazynRepository.java:33)
at io.github.mat3e.MagazynService.dodajdoDB(MagazynService.java:27)
at io.github.mat3e.MagazynServlet.doPost(MagazynServlet.java:52)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:859)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:542)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:146)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1588)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1345)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:480)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1557)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1247)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.Server.handle(Server.java:502)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:364)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:59)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:200)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3254)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3779)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:107)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604)
at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478)
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:348)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1360)
... 43 more
Caused by: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Pole nie może być NULL"NAZWA"
NULL not allowed for column "NAZWA"; SQL statement:
insert into MAGAZYN_SUROWCOW (ilosc, nazwa, typ, id) values (?, ?, ?, ?) [23502-200]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:459)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
at org.h2.message.DbException.get(DbException.java:205)
at org.h2.message.DbException.get(DbException.java:181)
at org.h2.table.Column.validateConvertUpdateSequence(Column.java:374)
at org.h2.table.Table.validateConvertUpdateSequence(Table.java:845)
at org.h2.command.dml.Insert.insertRows(Insert.java:187)
at org.h2.command.dml.Insert.update(Insert.java:151)
at org.h2.command.CommandContainer.update(CommandContainer.java:198)
at org.h2.command.Command.executeUpdate(Command.java:251)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:191)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:152)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197)
... 54 more
Hibernate: select max(id) from MAGAZYN_SUROWCOW
Hibernate: insert into MAGAZYN_SUROWCOW (ilosc, nazwa, typ, id) values (?, ?, ?, ?)
Process finished with exit code -1
WYGLĄDA TO OGÓLNIE TAK:
a) w pliku index.html po wcisnieciu przycisku wysylam metodą POST wartości do servleta
document.getElementById('btndodsurX').addEventListener('click', (event) => {
const xxnazwa = document.getElementById('nazwa');
const xxilosc = document.getElementById('ilosc');
event.preventDefault();
fetch("http://localhost:8080/magazyn", {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ ilosc: xxilosc.value, nazwa: xxnazwa.value, typ: "1"})
}
)
})
b) Dalej mam SERVLET z metodą, która to obsługuje:
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
var newSurowce = mapper.readValue(req.getInputStream(), Magazyn.class);
logger.info("MAGAZYN_SERVLET_METODA_DO_POST!!");
logger.info("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + req.getParameter(NAME2_PARAM));
resp.setContentType("application/json;charset=UTF-8");
mapper.writeValue(resp.getOutputStream(), service.dodajdoDB(newSurowce));
}
c) Dalej mam metodę z SERVICE:
public Magazyn dodajdoDB(Magazyn newSurowce) { repository.addMagazyn(newSurowce); return newSurowce; }
d)Dalej mam metodę z REPOSITORY:
Magazyn addMagazyn(Magazyn newSurowce){
var session = HibernateUtil.getSessionFactory().openSession();
var transaction = session.beginTransaction();
session.persist(newSurowce);
transaction.commit();
session.close();
return newSurowce;
}
e) Poniżej dodam jeszcze klasę związaną z Hibernate:
@Entity
@Table(name = "MAGAZYN_SUROWCOW")
public class Magazyn {
@Id
@GeneratedValue(generator = "inc")
@GenericGenerator(name = "inc", strategy = "increment")
private Integer id;
private String nazwa;
private String ilosc;
private Integer typ;
public Magazyn()
{ }
public Magazyn(Integer id, String nazwa, String ilosc, Integer typ)
{
this.id = id;
this.nazwa=nazwa;
this.ilosc=ilosc;
this.typ=typ;
}
public Integer getId() {
return id;
}
public String getNazwa() {
return nazwa;
}
public void setNazwa(String nazwa) {
nazwa = nazwa;
}
public String getIlosc() {
return ilosc;
}
public void setIlosc(String ilosc) {
ilosc = ilosc;
}
public Integer getTyp() {
return typ;
}
public void setTyp(String typ) {
typ = typ;
}
}
Utknąłem w martwym punkcie i przyznam, że naprawdę nie wiem już w czym problem. Gdy w servlecie jak chcę pobrać jakiś parametr/argument to jest on NULLem. Wygląda tak jakby metoda POST z frontendu napisana w JS nie przekazywała dalej wartości tych parametrów. Nie rozumiem tylko dlaczego, bo mogę pobrać z pola tekstowego wartosc i wyswietlic ja na ekranie z pomocą javascript i działa. W konsoli przeglądarki metoda post wraz z body istnieje. Dodałem loggera i całość dochodzi do metody doPOST w servlecie bo loguje w konsoli.
Problem zaczyna sie w tych liniach:
logger.info("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + req.getParameter(NAME2_PARAM));
i tutaj niestety req.getParameter rzuca NULLEM
resp.setContentType("application/json");
mapper.writeValue(resp.getOutputStream(), service.dodajdoDB(newSurowce));
idzie dalej do servisu, dalej do klasy magazyn, gdzie są metody związane z dodawaniem do DB, ale tam krzaczy, bo wartość jest nullowa.
Ma ktoś jakiś pomysł, albo chociaż wskazówkę gdzie szukąc/kiedy występuje taki błąd ?