Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

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.