Ajuda com uma list com duas classes (Resolvido)

37 respostas Resolvido
LostSpirit

Bom estou precisando de duas classes em uma lista
requisição e usuario
no meu bd a tabela de requisições tem uma chave estrangeira Usuario
então eu precisaria do usuario para fazer isso
user.setId(rs.getLong(“idusuario”));

public List<Requisicao> getList() {
    List<Requisicao> requisicoes = new ArrayList<>();
    String sql = "SELECT * FROM computador_requisicao";
    try {
        PreparedStatement stmt = con.prepareStatement(sql);
        ResultSet rs = stmt.executeQuery();
        while (rs.next()) {
            Requisicao req = new Requisicao();  
            Usuario user = new Usuario();
            req.setId(rs.getLong("id"));
            user.setId(rs.getLong("idusuario"));
            req.setNome(rs.getString("nome"));
            req.setData(rs.getDate("data_requisicao"));
            req.setMotivo(rs.getString("Observacao"));
            requisicoes.add();
        }
        stmt.close();
        rs.close();
    } catch (SQLException ex) {
        return null;
    }
    return requisicoes;
}

Alguém poderia me dar uma luuz de como eu resolveria essa situação?

37 Respostas

Lucas_Camara

Você precisa pegar esse id de usuário e realizar a consulta que retorna o usuário, ou jah retornar o usuário junto com um JOIN e obter os campos usando aliases.

LostSpirit

não man tipo meu objetivo com essa lista é mostrar todos as requisições no banco de dados
e nessa tabela de requisições tem a chave estrangeira idusuario
que é o id do usuario que a criou

minha dificuldade toda está em retornar esse valor para o metodo setId que está em outra classe
eu não quero pegar um usuario em especifico .

Lucas_Camara

Requisição possui um usuário?

Lucas_Camara

Não entendi essa dúvida. Onde está esse método setId?

LostSpirit

tipo eu quero retornar uma lista com todas as requisições no bd
essa tabela de requisições possui uma chave estrangeira IdUsuario

eu queria retornar todos os registros em uma tableview inclusive o id do usuario que criou a req

porém são duas classes diferentes
Requisições Usuario, UsuarioDAO,RequisicaoDAO

essa user.setId está na classe usuario ai que está o problema eu não conseguiria adicionar esse campo na lista pq ele está em outra classe

while (rs.next()) {
        Requisicao req = new Requisicao();  
        Usuario user = new Usuario();
        req.setId(rs.getLong("id"));
        req.setNome(rs.getString("nome"));
        req.setData(rs.getDate("data_requisicao"));
        req.setMotivo(rs.getString("Observacao"));
        requisicoes.add(req);

se fosse assim iria funcionar de boa
porém eu preciso desse campo e não faço ideia de como adicionar 2 classes na lista

LostSpirit

eu tou com um pouco de dúvida nessa parte
eu não utilizei extend em nenhuma
eu não sei se utilizo
Usuario extends requisição ou
Requisicao extends Usuario

Lucas_Camara

Nem um nem outro. Vc precisa entender a relação entre POSSUI UM e É UM. Nesse caso, penso que uma Requisicao possui um Usuario:

public class Requisicao {
	private Long id;
	private Usuario solicitante;
	// ... demais campos da requisição
	
	// getters e setters
}

Seguindo isso, basta retornar o usuário responsável por criar a Requisicao em cada requisição.

LostSpirit

**

“lucastody:

Nem um nem outro. Vc precisa entender a relação entre POSSUI UM e É UM. Nesse caso, penso que uma Requisicao possui um Usuario:

public class Requisicao {
	private Long id;
	private Usuario solicitante;
	// ... demais campos da requisição
	
	// getters e setters
}

Seguindo isso, basta retornar o usuário responsável por criar a Requisicao em cada requisição.

**

aaa sim, mesmo usuario criando a requisição
a requisição possui um usario?

ou usuario possui uma requisição kk
eu n consigo entender oq mudaria

no caso eu teria que fazer assim na list:
solicitante.setId(rs.getLong(“idusuario”));
?

e uma outra dúvida eu preciso usar extends em meus DAO
exemplo
usuarioDAO extends Usuario?

Lucas_Camara

Nesse caso, um usuário pode ter mais de uma requisição. Eu como usuário, posso criar N requisições.

Seu código ficará algo assim:

while(rs.next()) {
	Usuario solicitante = new Usuario();
	solicitante.setId(rs.getLong("idusuario"));
	
	Requisicao req = new Requisicao();  
	req.setId(rs.getLong("id"));
	req.setNome(rs.getString("nome"));
	req.setData(rs.getDate("data_requisicao"));
	req.setMotivo(rs.getString("Observacao"));
	req.setSolicitante(solicitante);
	
	requisicoes.add(req);

Lembrando que o Usuário terá apenas o ID, todos os outros campos continuarão nulos.

LostSpirit

e como eu conseguiria passar esse solicitante para a lista?

Lucas_Camara

Qual lista?

LostSpirit
public List<Requisicao> getList() {
    List<Requisicao> requisicoes = new ArrayList<>();
    String sql = "SELECT * FROM computador_requisicao";
    try {
        PreparedStatement stmt = con.prepareStatement(sql);
        ResultSet rs = stmt.executeQuery();
        while (rs.next()) {
            Requisicao req = new Requisicao();  
            Usuario user = new Usuario();
            req.setId(rs.getLong("id"));
            user.setId(rs.getLong("idusuario"));
            req.setNome(rs.getString("nome"));
            req.setData(rs.getDate("data_requisicao"));
            req.setMotivo(rs.getString("Observacao"));
            requisicoes.add();
        }
        stmt.close();
        rs.close();
    } catch (SQLException ex) {
        return null;
    }
    return requisicoes;
}

tudo isso faz parte de uma lista ( pois como eu falei eu quero pegar todos os dados do banco de dados, na tabela requisições.)

Lucas_Camara

Basta adicionar a requisição na lista (List<Requisicao> requisicoes) e retornar ela.

LostSpirit

no caso

Usuario solicitante = new Usuario();
	solicitante.setId(rs.getLong("idusuario"));
	Requisicao req = new Requisicao();  
	req.setId(rs.getLong("id"));
	req.setNome(rs.getString("nome"));
	req.setData(rs.getDate("data_requisicao"));
	req.setMotivo(rs.getString("Observacao"));
	req.setSolicitante(solicitante);
	requisicoes.add(req);

eu não estaria adicionando o campo solicitante a lista
requisicoes.add(req); pois só está adicionando o req.

Lucas_Camara

Isso. Ao adicionar o usuario na requisicao, vc jah consegue acessar ele de outros lugares (pois, lembre-se, a requisicao possui um usuario)

LostSpirit

eu entendi essa parte, mas tipo desse jeito no meu tableview não iria aparecer o id do usuario
pq eu não adicionei isso a lista.

Lucas_Camara

Adicionou. O id está dentro da requisição dentro do atributo solicitante (que é um Usuario). Para pegar o id do usuario, por exemplo, vc conseguiria asism: requisicoes.get(0).getSolicitante().getId().

Como você está montando essa tableview?

LostSpirit
@FXML
private TableView<Requisicao> tb;
@FXML
private TableColumn<Requisicao, Long> clmid;
@FXML
private TableColumn<Requisicao, Long> clmIdUser;
@FXML
private TableColumn<Requisicao, String> clmNome;
@FXML
private TableColumn<Requisicao, Date> clmDate;
@FXML

public void initTable() {

    clmid.setCellValueFactory(new PropertyValueFactory("id"));
    clmIdUser.setCellValueFactory(new PropertyValueFactory("id"));
    clmNome.setCellValueFactory(new PropertyValueFactory("nome"));
    clmDate.setCellValueFactory(new PropertyValueFactory("dataEntrada"));
    clmMotivo.setCellValueFactory(new PropertyValueFactory("motivo"));
    tb.setItems(atualizarTabela());
    
}
public ObservableList<Requisicao> atualizarTabela() {
    RequisicaoDAO dao = new RequisicaoDAO();
    requisicoes = FXCollections.observableArrayList(dao.getList());
    return requisicoes;
}

eu montei ela assim

Lucas_Camara

Pelo que pesquisei, é algo mais ou menos assim:

clmIdUser.setCellValueFactory(new Callback<CellDataFeatures<Requisicao, Long>, ObservableValue<Long>>() {
    @Override
    public ObservableValue<Long> call(CellDataFeatures<Requisicao, Long> data) {
		return data.getValue().getSolicitante().getId();
	}
});
LostSpirit

ai eu faria isso apenas com esse campo?
entendi
vou testar (mas nessa caso como é uma lista como ele retornaria todos os id’s? caso tenha mais de um registro)
desse modo parece que só retorna de um registro

opa man pode me tirar uma dúvida? Estava tentando de outro metodo que creio que seja mais fácil
porém estou com uma dúvida:

public void initTable() throws SQLException {
    Requisicao requisicao = new Requisicao();
    Usuario usuario = new Usuario();
    Connection con = ConnectionFactory.getConnection();
    
    PreparedStatement stmt = con.prepareStatement("SELECT * FROM computador_requisicao");
    ResultSet rs = stmt.executeQuery();
    while (rs.next()){
        requisicaolist.add(new Requisicao(rs.getLong("id"), rs.getLong("idusuario"), rs.getString("nome")));
    }
    clmid.setCellValueFactory(new PropertyValueFactory("id"));
    clmIdUser.setCellValueFactory(new PropertyValueFactory("id"));
    clmNome.setCellValueFactory(new PropertyValueFactory("nome"));
    clmDate.setCellValueFactory(new PropertyValueFactory("dataEntrada"));
    clmMotivo.setCellValueFactory(new PropertyValueFactory("motivo"));
    tb.setItems(requisicaolist());
    
}

    while (rs.next()){
        requisicaolist.add(new Requisicao(rs.getLong("id"), rs.getLong("idusuario"), rs.getString("nome")));
    }

eu teria que criar esse construtor na classe requisicao
onde teria o id da requisição e o id do usuario?
ex:

public Requisicao(Long id, Long idUsuario) {
    this.id = id;
    this.idUsuario = ?
}

como eu conseguiria fazer isso?

Lucas_Camara

Isso o javaFX vai fazer para vc.

Lucas_Camara

Fazendo assim, vc terá mais problemas. Não misture as camadas.

LostSpirit

ah simm vlw

LostSpirit

ahh pensei que fosse mais fácill
mas é possível fazer isso?

fazer essa comparação nesse construtor?

Lucas_Camara

Você consegue criar um construtor para receber os dois dados sem problemas.

LostSpirit

Poderia me dar um exemplo manin?
estou pensando em fazer algo com isso
mas não faço ideia de como fazer isso .

e eu tinha me esquecido desse negocio de agregração e composição
mt obrigado mesmo, não tinha passado na minha cabeça essa opção.

LostSpirit

tentei fazer algo desse tipo, mas deu altas erros mesmo importando
ele funciona porém o campo id usuario ta mostrando os id’s das requisições e não do usuario;

provavelmente por esse motivo:
@FXML
private TableColumn<Requisicao, Long> clmIdUser;

ele ta pegando o get do id da requisição e não usuario

não consigo imaginar nada para resolver isso.

esse codigo que você mandou da esse error:

Lucas_Camara

No método call vc tem que mudar de Observable<String> para Observable<Long>.

LostSpirit

então mano eu não tinha percebido, mas continuou com esse error

private ObservableList requisicao = FXCollections.observableArrayList();
eu tentei botar com requisicao e acontece isso:

Lucas_Camara

Vc tem que usar um método que retornar a Requisicao a partir desse objeto Observable

LostSpirit
public ObservableList atualizarTabela() {

RequisicaoDAO dao = new RequisicaoDAO();

requisicao = FXCollections.observableArrayList(dao.getList());

return requisicao;

}

eu tenho esse metodo aqui

seria isso?

não entendi mt bem.

Lucas_Camara

Putz, foi mal, não é Observable não, é dessa classe CellDataFeatures. Em vez de chamar o getValue, veja quais outros métodos tem disponível e que retorne a requisição.

LostSpirit

vou dar uma olhada antes disso
eu fiquei com uma dúvida man

private ObservableList requisicao = FXCollections.observableArrayList();

clmIdUser.setCellValueFactory(new Callback<CellDataFeatures<Requisicao, Long>, ObservableValue<Long>>() {
    @Override
    public ObservableValue<Long> call(CellDataFeatures<Requisicao, Long> requisicao) {
  return requisicao.add(Requisicao).getSolicitante().getId();

}
});

o nome da observeble list é requisicao
public ObservableValue call(CellDataFeatures<Requisicao, Long> requisicao)
nessa parte eu botaria Long> requisicao ou Long>Requisicao

se for requisicao
tem esses metodos:


e se o return for com a classe Requisicao tem esses:

se for Requisicao
tem esses:


LostSpirit

seria
public ObservableValue call(CellDataFeatures<Requisicao, Long> requisicao) {

ou

public ObservableValue call(CellDataFeatures<Requisicao, Long> Requisicao) {

return requisicao.add(Requisicao).getSolicitante().getId();

sendo que minha private ObservableList requisicao = FXCollections.observableArrayList(); é assim

creio que seja esse codigo:

clmIdUser.setCellValueFactory(new Callback<CellDataFeatures<Requisicao, Long>, ObservableValue<Long>>() {
@Override
public ObservableValue<Long> call(CellDataFeatures<Requisicao, Long> requisicao) {
	return requisicao.getValue().getSolicitante().getId();
}
});

porém no return fica dando incompatibilidade de convertert long para observableList

Lucas_Camara

Tente alterar para isso:

clmIdUser.setCellValueFactory(new Callback<CellDataFeatures<Requisicao, Long>, Long>() {
	@Override
	public Long call(CellDataFeatures<Requisicao, Long> requisicao) {
		return requisicao.getValue().getSolicitante().getId();
	}
});
LostSpirit

eu tinha tentado, mas deu esses erros.

LostSpirit
Solucao aceita
clmIdUser.setCellValueFactory(new Callback<CellDataFeatures<Requisicao, Long>, ObservableValue<Long>>() {
    public ObservableValue<Long> call(CellDataFeatures<Requisicao, Long> requisicao) {
	return new SimpleObjectProperty(requisicao.getValue().getSolicitante().getId());
}
    });

deu certo desse jeito .

Criado 26 de junho de 2019
Ultima resposta 28 de jun. de 2019
Respostas 37
Participantes 2