11
respostas

Não consegui realizar o último exercício do LanceDaoTest. NullPointerException

Criei o LanceDaoTest e o LanceBuilder, mas está dando nullPointerException

public class LanceDaoTest {

private LanceDao dao;
private EntityManager em;


@BeforeEach
public void beforeEach() {
    em = JPAUtil.getEntityManager();
    this.dao = new LanceDao(em);
    this.em.getTransaction().begin();
}

@AfterEach
public void afterEach() {
    em.getTransaction().rollback();
}



@Test
public void deveriaBuscarMaiorLanceDoLeilao() {

        Usuario usuario = new UsuarioBuilder()
                .comNome("Fulano")
                .comEmail("fulano@email.com")
                .comSenha("12345678")
                .criar();

        em.persist(usuario);

        Leilao leilao = new LeilaoBuilder()
                .comNome("Mochila")
                .comValorInicial("500")
                .comData(LocalDate.now())
                .comUsuario(usuario)
                .criar();

        em.persist(leilao);

        Lance lance = new LanceBuilder()
                .comUsuario(usuario)
                .comValor("600")
                .comLeilao(leilao)
                .criar();

        em.persist(lance);

        Lance acheiMaiorLance = this.dao.buscarMaiorLanceDoLeilao(leilao);
        assertNotNull(acheiMaiorLance);
    }

}

public class LanceBuilder {

private BigDecimal valor;
private Usuario usuario;
private LocalDate data;
private Leilao leilao;


public LanceBuilder comValor(String valor){
    this.valor = new BigDecimal(valor);
    return this;
}

public LanceBuilder comUsuario(Usuario usuario){
    this.usuario = usuario;
    return this;
}

public LanceBuilder comData(LocalDate data){
    this.data = data;
    return this;
}


public LanceBuilder comLeilao(Leilao leilao){
    this.leilao = leilao;
    return this;
}

public Lance criar() {
    return new Lance(usuario, valor, data);
}
11 respostas

Oi Carolina,

Talvez seja o import da anotação @Test.

O import correto deve ser: org.junit.jupiter.api.Test

Oi Rodrigo, Era esse problema inicial. Mas, agora, ele está reclamando de que o LEILAO_ID não pode ser nulo. .

Lance lance = new LanceBuilder() .comUsuario(usuario) .comValor("600") .comLeilao(leilao) .criar();

16:09:14.008 [main] WARN org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 23502, SQLState: 23502
16:09:14.008 [main] ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - NULL not allowed for column "LEILAO_ID"; SQL statement:
insert into Lance (id, data, leilao_id, usuario_user_id, valor) values (null, ?, ?, ?, ?) [23502-200]
16:09:14.007 [main] DEBUG org.hibernate.engine.jdbc.spi.SqlExceptionHelper - could not execute statement [n/a]
org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: NULL not allowed for column "LEILAO_ID"; SQL statement:
insert into Lance (id, data, leilao_id, usuario_user_id, valor) values (null, ?, ?, ?, ?) [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)

Olá Carol, tudo bem?

Vc chega a fazer o set do ID em algum lugar no método de insert? O ID está como auto-increment?

Oi Thiago, A gente não seta o ID nem no usuário e nem no leilão. Deveria setar manualmente no Lance?

O que eu percebi é que o construtor do Lance não tinha o Leilao. Eu adicionei, mas agora ele dá erro de

java.lang.IllegalArgumentException: Could not locate named parameter [leilao], expecting one of [] at org.hibernate.query.internal.ParameterMetadataImpl.getNamedParameterDescriptor(ParameterMetadataImpl.java:229) at org.hibernate.query.internal.ParameterMetadataImpl.getQueryParameter(ParameterMetadataImpl.java:198) at org.hibernate.query.internal.QueryParameterBindingsImpl.getBinding(QueryParameterBindingsImpl.java:188) at org.hibernate.query.internal.AbstractProducedQuery.setParameter(AbstractProducedQuery.java:490) at org.hibernate.query.internal.AbstractProducedQuery.setParameter(AbstractProducedQuery.java:111) at br.com.alura.leilao.dao.LanceDao.buscarMaiorLanceDoLeilao(LanceDao.java:36) at br.com.alura.leilao.dao.LanceDaoTest.deveriaBuscarMaiorLanceDoLeilao(LanceDaoTest.java:72) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686) at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84) at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115) at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:212) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:208) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:137) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:71) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) at java.util.ArrayList.forEach(ArrayList.java:1257) at

É possível disponibilizar a resposta desse desafio para que eu possa comparar e ver o que estou fazendo diferente?

Carolina,

No Lance você vai precisar setar o leilão ao qual ele pertence:

public Lance criar() {
    Lance lance = new Lance(usuario, valor, data);
    lance.setLeilao(leilao);
    return lance;
}

Oi Rodrigo,

Eu já tinha feito isso. Mas continua o erro reportado acima.

java.lang.IllegalArgumentException: Could not locate named parameter [leilao], expecting one of [] at org.hibernate.query.internal.ParameterMetadataImpl.getNamedParameterDescriptor(ParameterMetadataImpl.java:229) at org.hibernate.query.internal.ParameterMetadataImpl.getQueryParameter(ParameterMetadataImpl.java:198)

Meu LanceBuilder public class LanceBuilder {

private BigDecimal valor;
private Usuario usuario;
private LocalDate data;
private Leilao leilao;


public LanceBuilder comValor(String valor){
    this.valor = new BigDecimal(valor);
    return this;
}

public LanceBuilder comUsuario(Usuario usuario){
    this.usuario = usuario;
    return this;
}

public LanceBuilder comData(LocalDate data){
    this.data = data;
    return this;
}


public LanceBuilder comLeilao(Leilao leilao){
    this.leilao = leilao;
    return this;
}

public Lance criar() {
    Lance lance = new Lance(usuario, valor, data);
    lance.setLeilao(leilao);
    return lance;

}

Meu LanceDaoTest

public class LanceDaoTest {

private LanceDao dao;
private EntityManager em;


@BeforeEach
public void beforeEach() {
    em = JPAUtil.getEntityManager();
    this.dao = new LanceDao(em);
    this.em.getTransaction().begin();
}

@AfterEach
public void afterEach() {
    em.getTransaction().rollback();
}



@Test
public void deveriaBuscarMaiorLanceDoLeilao() {

        Usuario usuario = new UsuarioBuilder()
                .comNome("fulano")
                .comEmail("fulano@email.com")
                .comSenha("12345678")
                .criar();

        em.persist(usuario);

        Leilao leilao = new LeilaoBuilder()
                .comNome("Mochila")
                .comValorInicial("500")
                .comData(LocalDate.now())
                .comUsuario(usuario)
                .criar();

        em.persist(leilao);


        Lance lance = new LanceBuilder()
                .comUsuario(usuario)
                .comValor("600")
                .comData(LocalDate.now())
                .comLeilao(leilao)
                .criar();


        em.persist(lance);

        Lance acheiMaiorLance = this.dao.buscarMaiorLanceDoLeilao(leilao);
        assertNotNull(acheiMaiorLance);
    }

}

Oi Carolina,

Parece que o problema então é na classe LanceDao, posta o código dessa sua classe aqui.

@Repository public class LanceDao {

private EntityManager em;

@Autowired
public LanceDao(EntityManager em) {
    super();
    this.em = em;
}


public Lance salvar(Lance lance) {
    return em.merge(lance);
}


public Lance buscarMaiorLanceDoLeilao(Leilao leilao) {
    return em.createQuery("SELECT l FROM Lance l WHERE l.valor = (SELECT MAX(lance.valor) FROM Lance lance)", Lance.class)
            .setParameter("leilao", leilao)
            .getSingleResult();
}

}

Oi Carolina,

Faltou adicionar o leilão na query:

"SELECT l FROM Lance l WHERE l.valor = (SELECT MAX(lance.valor) FROM Lance lance WHERE lance.leilao = :leilao)"

Obrigada, Rodrigo! Era isso mesmo. Olhei os métodos todos, mas esqueci de alterar o select.