JavaFX table row color, too many database connections - mysql

I want to to print my row red when book is out of stock but i am getting error like that every time i try new idea to manage that:
"com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:
Data source rejected establishment of connection, message from
server: "Too many connections"
Even if i try to close all connections in same loop...
So here we go:
private boolean checkIfOutOfStock(BookDetail book) throws SQLException{
String query = "select * from tbl_loan where book_id = " + book.getId() + " ";
dc = new DbConnection();
conn = dc.connect();
PreparedStatement checkPst = conn.prepareStatement(query);
ResultSet checkRs = checkPst.executeQuery(query);
if(checkRs.next()){
checkRs.close();
checkPst.close();
return true;
} else
{
checkRs.close();
checkPst.close();
return false;
}
}
#Override
public void initialize(URL location, ResourceBundle resources) {
dc = new DbConnection();
conn = dc.connect();
selectionModel = editTabPane.getSelectionModel();
editTableBooks.setRowFactory(tv -> new TableRow<BookDetail>() {
#Override
public void updateItem(BookDetail item, boolean empty) {
super.updateItem(item, empty) ;
if (item == null) {
setStyle("");
} else
try {
if (checkIfOutOfStock(item)) {
setStyle("-fx-background-color: tomato;");
} else {
setStyle("");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
It works fine until i slide up and down table few times... its like everytime i slide table im opening new connection. Any idea how to solve it?
Hey do you mean something like that?
editTableBooks.setRowFactory(tv -> new TableRow<BookDetail>() {
#Override
public void updateItem(BookDetail item, boolean empty) {
super.updateItem(item, empty) ;
Platform.runLater(new Runnable() {
#Override
public void run() {
if (item == null) {
setStyle("");
} else
try {
if (checkIfOutOfStock(item)) {
setStyle("-fx-background-color: tomato;");
} else {
setStyle("");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
});
It doesn't change anything or i just didn't get it :P

Related

actframework can't save in database using $.merge

i'am trying to read data from a form and save it to database.first i read entity from database and use $.merge(formdata).filter("-id").to(entity) .I print the value and it's changed successful.But when i call dao.save it do nothing;
the action code below
#PutAction("{id}")
public void update(#DbBind("id") #NotNull Category cate,Category category, ActionContext context) {
notFoundIfNull(cate);
try {
$.merge(category).filter("-id").to(cate);
System.out.print("name is " + cate.getName());
// cate.setName("test"); // success
this.dao.save(cate);
// redirect("/admin/categories");
} catch (io.ebean.DataIntegrityException e) {
context.flash().error(e.getMessage());
render("edit", category);
}
}
dao.save successful when i call cate.setName("test");
Can someone help me solve this problem?
I solved this problem by myself using the following code
public void mergeTo(Base target){
if(!this.getClass().isAssignableFrom(target.getClass())){
return;
}
Method[] methods = this.getClass().getMethods();
for(Method fromMethod: methods){
if(fromMethod.getDeclaringClass().equals(this.getClass())
&& fromMethod.getName().startsWith("get")){
String fromName = fromMethod.getName();
String toName = fromName.replace("get", "set");
try {
Method toMetod = target.getClass().getMethod(toName, fromMethod.getReturnType());
Object value = fromMethod.invoke(this, (Object[])null);
if(value != null){
toMetod.invoke(target, value);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

JavaFx combobox from mysql

Good Day I am completely new to coding. I am building an app which uses a combobox besides other library items. The problem I am facing is that while attempting to populate combobox items from a Mysql Db the item values get duplicated each time the drop down is clicked.
How I can keep this from happening ? I do understand that my approach itself could be erroneous.
#FXML
public void getStation() {
String sqlStationName = " select * from station ";
try {
conn = (Connection) DBConnection.connect();
PreparedStatement pstStn = conn.prepareStatement(sqlStationName);
ResultSet stnRS = pstStn.executeQuery(sqlStationName);
while (stnRS.next()) {
comboBoxStation.getItems().add(stnRS.getString("stationName"));
}
stnRS.close();
pstStn.close();
conn.close();
} catch (SQLException ex) {
System.err.println("ERR" + ex);
}
}
Ok so I moved the function to the initialize() method in the controller and created an Observabale list called station
private ObservableList<String> stationsList = FXCollections.observableArrayList();
#Override
public void initialize(URL url, ResourceBundle rb) {
//
String sqlStationName = " select * from station ";
try {
conn = (Connection) DBConnection.connect();
PreparedStatement pstStn = conn.prepareStatement(sqlStationName);
ResultSet stnRS = pstStn.executeQuery(sqlStationName);
while (stnRS.next()) {
stationsList.add(stnRS.getString("stationName"));
}
stnRS.close();
pstStn.close();
conn.close();
} catch (SQLException ex) {
System.err.println("ERR" + ex);
}
}
and then left only this line in the original function....seems to be working.
#FXML
private void getStation() {
comboBoxStation.setItems(stationsList);
}

JavaFX, SceneBuilder, Populating TableView with MySQL Result Set

I have finally overcome my issue with a NPE in my code whilst learning FX/FXML. I now however have a different problem, a window opens with my TableView however there is no content in the table at all. As you cann I have printed out the JobList to make sure there is content being returned, and this returns three jobs (the correct amount). Am I missing something that binds the table to the returned list?
Here is the code;
public class SecondInterface implements Initializable {
private JobDataAccessor jAccessor;
private String aQuery = "SELECT * FROM progdb.adamJobs";
private Parent layout;
private Connection connection;
#FXML
TableView<Job> tView;
public void newI(Connection connection) throws Exception {
Stage primaryStage;
primaryStage = MainApp.primaryStage;
this.connection = connection;
System.out.println(connection);
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Test1.fxml"));
fxmlLoader.setController(this);
try {
layout = (Parent) fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
primaryStage.getScene().setRoot(layout);
}
public Parent getLayout() {
return layout;
}
#Override
public void initialize(URL url, ResourceBundle rb) {
jAccessor = new JobDataAccessor();
try {
System.out.println("This connection: " + connection);
System.out.println("This query: " + aQuery);
List<Job> jList = jAccessor.getJobList(connection, aQuery);
for (Job j : jList) {
System.out.println(j);
}
tView.getItems().addAll(jAccessor.getJobList(connection, aQuery));
} catch (SQLException e) {
e.printStackTrace();
}
}
}

Future get() gets nullpointer exeception in java

I'm implementing a function that detects if there is a webcam. This piece of code works fine in windows and I had no problem with it in linux centos OS. Now I'm trying to run the same code in Ubuntu, here an exception is thrown.
Exception in thread "main" java.lang.NullPointerException
at CameraProperties.CheckForCameraPlugin.check(CheckForCameraPlugin.java:51)
at Main.Main.main(Main.java:39)
The code is given below.
public boolean check()
{
boolean b = true;
service = Executors.newFixedThreadPool(1);
task = service.submit(new InitialCameraChecker());
try
{
final String str;
// waits the 10 seconds for the Callable.call to finish.
str = task.get();
if (str.matches("nodevice"))
{
b = false;//Return false if no camera device found
}
else
{
b = true;
}
}
catch (InterruptedException | ExecutionException ex)
{
msgbox.showJoptionPane(15);
}
service.shutdownNow();
return b;
}
The callable class is given below
class InitialCameraChecker implements Callable<String>
{
private List<Integer> devices = new ArrayList<Integer>();
private final static String VERSION_ID = "1.0.0";
private String res;
//Checking for the Camera
public String call()
{
try
{
loadWebcam();
discoverDevices();
if (devices.isEmpty())
{
res = "nodevice";//No we cam device found
}
else
{
res = "founddevice";//Found Web Cam Device
}
}
catch (Exception ex)
{
System.out.println("Exception_logout" + ex.toString());
}
return res;
}
//Discovering the camera device
private void discoverDevices()
{
for (int i = 0; i < 10; i++)
{
CvCapture cap = null;
try
{
cap = cvCreateCameraCapture(i);
int res = cvGrabFrame(cap);
if (res > 0)
{
devices.add(i);
break;
}
}
catch (Exception e)
{
System.out.println("Exception in camaracheck Thread1");
}
finally
{
if (cap != null)
{
try
{
cvReleaseCapture(cap.pointerByReference());
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
}
//Loading the dlls for starting the camera
private void loadWebcam()
{
String tmpDir = System.getProperty("java.io.tmpdir");
File faPath = new File(tmpDir + File.separator + "WebcamApplet_" + VERSION_ID.replaceAll("\\.", "-"));
System.setProperty("jna.library.path", faPath.getAbsolutePath());
}
}
Please tell me what is the problem. This works fine in windows.

Glassfish "Connection closed" error with a connection pool, JDBC, and SQL Server 2008

When I try to do more than one transaction in a JSF page, I get the following error:
A potential connection leak detected for connection pool MSSQL. The stack trace of the thread is provided below :
com.sun.enterprise.resource.pool.ConnectionPool.setResourceStateToBusy(ConnectionPool.java:324)
com.sun.enterprise.resource.pool.ConnectionPool.getResourceFromPool(ConnectionPool.java:758)
com.sun.enterprise.resource.pool.ConnectionPool.getUnenlistedResource(ConnectionPool.java:632)
com.sun.enterprise.resource.pool.AssocWithThreadResourcePool.getUnenlistedResource(AssocWithThreadResourcePool.java:196)
com.sun.enterprise.resource.pool.ConnectionPool.internalGetResource(ConnectionPool.java:526)
com.sun.enterprise.resource.pool.ConnectionPool.getResource(ConnectionPool.java:381)
com.sun.enterprise.resource.pool.PoolManagerImpl.getResourceFromPool(PoolManagerImpl.java:245)
com.sun.enterprise.resource.pool.PoolManagerImpl.getResource(PoolManagerImpl.java:170)
com.sun.enterprise.connectors.ConnectionManagerImpl.getResource(ConnectionManagerImpl.java:338)
com.sun.enterprise.connectors.ConnectionManagerImpl.internalGetConnection(ConnectionManagerImpl.java:301)
com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:190)
com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:165)
com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:160)
com.sun.gjc.spi.base.DataSource.getConnection(DataSource.java:113)
cl.codesin.colegios.util.persistencia.DAOManejador.abrir(DAOManejador.java:126)
Please notice the last line I pasted:
cl.codesin.colegios.util.persistencia.DAOManejador.abrir(DAOManejador.java:126)
abrir does the following:
public void abrir() throws SQLException {
try
{
if(this.con==null || this.con.isClosed())
this.con = fuenteDatos.getConnection();
}
catch(SQLException e)
{
throw e;
}
}
It works in a singleton DAO manager this way: the DAO manager has one instance of each DAO and manages a single connection that every DAO shares. When a DAO is requested, it does the following:
public DAORegion getDAOregion() throws SQLException {
try
{
if(con == null) //con is the connection the DAO manager uses
{
this.abrir();
}
}
catch(SQLException e)
{
throw e;
}
if(this.DAOregion==null)
{
this.DAOregion = new DAORegion(this.con);
}
return DAOregion;
}
When closing a connection, the manager just calls to con.close() without anything else.
By the way, I have no persistence.xml since I'm working with JDBC.
What am I doing wrong? Thank you beforehand.
EDIT: By desactivating the leak detection from the Glassfish server I could avoid the exception, however I'm still getting a "Connection closed" error. Worst is, now I don't know exactly where the error is being thrown.
EDIT 2: I changed my DAO manager again. Here's the implementation.
public class DAOManejador {
public static DAOManejador getInstancia() {
return DAOManejadorSingleton.INSTANCIA;
}
//This is just a sample, every getDAOXXX works the same.
public DAOUsuario getDAOusuario() throws SQLException {
try
{
if(con == null)
{
this.abrir();
}
}
catch(SQLException e)
{
throw e;
}
if(this.DAOusuario==null)
{
this.DAOusuario = new DAOUsuario(this.con, this.stmt, this.res);
}
return DAOusuario;
}
public void abrir() throws SQLException {
try
{
if(this.con==null || this.con.isClosed())
this.con = fuenteDatos.getConnection();
}
catch(SQLException e)
{
throw e;
}
}
public void iniciaTransaccion() throws SQLException {
try
{
con.setAutoCommit(false);
}
catch(SQLException e)
{
throw e;
}
}
public void cierraTransaccion() throws SQLException {
try
{
con.setAutoCommit(true);
}
catch(SQLException e)
{
throw e;
}
}
public void comprometer() throws SQLException {
try
{
con.commit();
}
catch(SQLException e)
{
throw e;
}
}
public void deshacer() throws SQLException {
try
{
con.rollback();
}
catch(SQLException e)
{
throw e;
}
}
public void cerrar() throws SQLException {
try
{
if(this.stmt!=null && !this.stmt.isClosed())
stmt.close();
if(this.res!=null && !this.res.isClosed())
this.res.close();
if(this.con!=null && !this.con.isClosed())
con.close();
}
catch(SQLException e)
{
throw e;
}
}
public void comprometerYTerminarTransaccion() throws SQLException {
try
{
this.comprometer();
this.cierraTransaccion();
}
catch(SQLException e)
{
throw e;
}
}
public void comprometerYCerrarConexion() throws SQLException {
try
{
this.comprometer();
this.cierraTransaccion();
this.cerrar();
}
catch(SQLException e)
{
throw e;
}
}
//Protegidos
#Override
protected void finalize() throws SQLException, Throwable
{
try
{
this.cerrar();
}
finally
{
super.finalize();
}
}
//Private
private DataSource fuenteDatos;
private Connection con = null;
private PreparedStatement stmt = null;
private ResultSet res = null;
private DAOUsuario DAOusuario = null;
private DAORegion DAOregion = null;
private DAOProvincia DAOprovincia = null;
private DAOComuna DAOcomuna = null;
private DAOColegio DAOcolegio = null;
private DAOManejador() throws Exception {
try
{
InitialContext ctx = new InitialContext();
this.fuenteDatos = (DataSource)ctx.lookup("jndi/MSSQL");
}
catch(Exception e){ throw e; }
}
private static class DAOManejadorSingleton {
public static final DAOManejador INSTANCIA;
static
{
DAOManejador dm;
try
{
dm = new DAOManejador();
}
catch(Exception e)
{ dm=null; }
INSTANCIA = dm;
}
}
}
What I did now is to provide a single access point for every DAO. When a DAO wants to use a statement or a resource, they'll all use the same one. When they need to open again one, the system does the following:
public abstract class DAOGenerico<T> {
//Protected
protected final String nombreTabla;
protected Connection con;
protected PreparedStatement stmt;
protected ResultSet res;
protected DAOGenerico(Connection con, PreparedStatement stmt, ResultSet res, String nombreTabla) {
this.nombreTabla = nombreTabla;
this.con = con;
this.stmt = stmt;
this.res = res;
}
//Prepares a query
protected final void prepararConsulta(String query) throws SQLException
{
try
{
if(this.stmt!=null && !this.stmt.isClosed())
this.stmt.close();
this.stmt = this.con.prepareStatement(query);
}
catch(SQLException e){ throw e; }
}
//Gets a ResultSet
protected final void obtenerResultados() throws SQLException {
try
{
if(this.res!=null && !this.res.isClosed())
this.res.close();
this.res = this.stmt.executeQuery();
}
catch(SQLException e){ throw e; }
}
}
And it still doesn't work.
I tried not doing anything when closing the connection. I commented the code in the cerrar method, and for some reason, it works! Even when it's a bad practice! Is it okay to keep it like that, or should I find a way to close a connection?
Disregard this, I found what's wrong. I hope someone can make good use of this in the future.
The problem
if(this.con==null || this.con.isClosed())
this.con = fuenteDatos.getConnection();
Each time I try to open a connection, I get a completely brand new connection. What's the problem with this?
public DAOUsuario getDAOusuario() throws SQLException {
try
{
if(con == null)
{
this.abrir();
}
}
catch(SQLException e)
{
throw e;
}
if(this.DAOusuario==null)
{
this.DAOusuario = new DAOUsuario(this.con, this.stmt, this.res);
}
return DAOusuario;
}
Only when I create a new instance of the DAO I assign it a new connection. What will happen in the following case then?
DAOManejador daoManager = DAOManejador.getInstancia(); //Get an instance of the DAO manager
daoManager.abrir(); //Open the connection
DAOUsuario daoUser = daoManager.getDAOusuario(); //Get a DAOUsuario, a type of DAO. It'll have the same connection as the DAOManager, and it'll be stored in the instance of the DAO manager
... //Do database stuff
daoManager.cerrar(); //Close the connection
daoManager.abrir(); //Open the connection again. Note that this will be a new instance of the conection rather than the old one
If, from here, you try to do database stuff, you'll get a Connection closed error since daoUser will still hold the old connection.
What I did
I modified the DAO manager class. It no longer has a getDAOXXX() per DAO, but rather the following:
public DAOGenerico getDAO(Tabla t) throws SQLException {
try
{
if(con == null || this.con.isClosed())
{
this.abrir();
}
}
catch(SQLException e)
{
throw e;
}
switch(t)
{
case REGION:
return new DAORegion(this.con, this.stmt, this.res);
case PROVINCIA:
return new DAOProvincia(this.con, this.stmt, this.res);
case COMUNA:
return new DAOComuna(this.con, this.stmt, this.res);
case USUARIO:
return new DAOUsuario(this.con, this.stmt, this.res);
case COLEGIO:
return new DAOColegio(this.con, this.stmt, this.res);
default:
throw new SQLException("Se intentó vincular a una tabla que no existe.");
}
}
Each time the user requests a DAO, it'll ask the manager to return the correct type of DAO. But instead of storing each instance, the manager will create new instances depending on the current connection (con is the connection, stmt is a PreparedStatement and res is a ResultSet - they will be used so they can be closed when the manager closes the connection so nothing leaks). Tabla is an enum holding the current table names in the database so it can return the correct DAO. This worked with no problems whatsoever. The rest of the class is the same, so if you want to use it, just replace the DAOUsuario method with the one above and it should work fine.