db: Prevent NullPointerException on GenericDaoBase (#4268)

* Prevent NullPointerException on GenericDaoBase

* Fix checkstyle: remove unused import
This commit is contained in:
Gabriel Beims Bräscher 2020-08-17 07:43:46 -03:00 committed by GitHub
parent c383269a20
commit 3fe724bd32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 79 additions and 35 deletions

View File

@ -162,6 +162,9 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
protected static final String SELECT_LAST_INSERT_ID_SQL = "SELECT LAST_INSERT_ID()"; protected static final String SELECT_LAST_INSERT_ID_SQL = "SELECT LAST_INSERT_ID()";
public static final Date DATE_TO_NULL = new Date(Long.MIN_VALUE); public static final Date DATE_TO_NULL = new Date(Long.MIN_VALUE);
private static final String INTEGRITY_CONSTRAINT_VIOLATION = "23000";
private static final int DUPLICATE_ENTRY_ERRO_CODE = 1062;
protected static final SequenceFetcher s_seqFetcher = SequenceFetcher.getInstance(); protected static final SequenceFetcher s_seqFetcher = SequenceFetcher.getInstance();
public static <J> GenericDao<? extends J, ? extends Serializable> getDao(Class<J> entityType) { public static <J> GenericDao<? extends J, ? extends Serializable> getDao(Class<J> entityType) {
@ -850,13 +853,23 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
ub.clear(); ub.clear();
return result; return result;
} catch (final SQLException e) { } catch (final SQLException e) {
if (e.getSQLState().equals("23000") && e.getErrorCode() == 1062) { handleEntityExistsException(e);
throw new EntityExistsException("Entity already exists ", e);
}
throw new CloudRuntimeException("DB Exception on: " + pstmt, e); throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
} }
} }
/**
* If the SQLException.getSQLState is of 23000 (Integrity Constraint Violation), and the Error Code is 1062 (Duplicate Entry), throws EntityExistsException.
* @throws EntityExistsException
*/
protected static void handleEntityExistsException(SQLException e) throws EntityExistsException {
boolean isIntegrityConstantViolation = INTEGRITY_CONSTRAINT_VIOLATION.equals(e.getSQLState());
boolean isErrorCodeOfDuplicateEntry = e.getErrorCode() == DUPLICATE_ENTRY_ERRO_CODE;
if (isIntegrityConstantViolation && isErrorCodeOfDuplicateEntry) {
throw new EntityExistsException("Entity already exists ", e);
}
}
@DB() @DB()
protected Attribute findAttributeByFieldName(String name) { protected Attribute findAttributeByFieldName(String name) {
return _allAttributes.get(name); return _allAttributes.get(name);
@ -1450,11 +1463,8 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
} }
txn.commit(); txn.commit();
} catch (final SQLException e) { } catch (final SQLException e) {
if (e.getSQLState().equals("23000") && e.getErrorCode() == 1062) { handleEntityExistsException(e);
throw new EntityExistsException("Entity already exists: ", e); throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
} else {
throw new CloudRuntimeException("DB Exception on: " + pstmt, e);
}
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw new CloudRuntimeException("Problem with getting the ec attribute ", e); throw new CloudRuntimeException("Problem with getting the ec attribute ", e);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {

View File

@ -20,21 +20,44 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
import javax.persistence.EntityExistsException;
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class GenericDaoBaseTest { public class GenericDaoBaseTest {
@Mock @Mock
ResultSet resultSet; ResultSet resultSet;
@Mock
SQLException mockedSQLException;
private static final String INTEGRITY_CONSTRAINT_VIOLATION = "23000";
private static final int DUPLICATE_ENTRY_ERRO_CODE = 1062;
@Before
public void prepareTests() throws SQLException {
Mockito.when(resultSet.getObject(1)).thenReturn(false);
Mockito.when(resultSet.getBoolean(1)).thenReturn(false);
Mockito.when(resultSet.getObject(1)).thenReturn((short) 1);
Mockito.when(resultSet.getShort(1)).thenReturn((short) 1);
Mockito.when(resultSet.getObject(1)).thenReturn(0.1f);
Mockito.when(resultSet.getFloat(1)).thenReturn(0.1f);
Mockito.when(resultSet.getObject(1)).thenReturn(0.1d);
Mockito.when(resultSet.getDouble(1)).thenReturn(0.1d);
Mockito.when(resultSet.getObject(1)).thenReturn(1l);
Mockito.when(resultSet.getLong(1)).thenReturn(1l);
Mockito.when(resultSet.getInt(1)).thenReturn(1);
Mockito.when(resultSet.getObject(1)).thenReturn((byte) 1);
Mockito.when(resultSet.getByte(1)).thenReturn((byte) 1);
}
@Test @Test
public void getObjectBoolean() throws SQLException { public void getObjectBoolean() throws SQLException {
Mockito.when(resultSet.getObject(1)).thenReturn(false);
Mockito.when(resultSet.getBoolean(1)).thenReturn(false);
Assert.assertFalse(GenericDaoBase Assert.assertFalse(GenericDaoBase
.getObject(Boolean.class, resultSet, 1)); .getObject(Boolean.class, resultSet, 1));
Mockito.verify(resultSet).getBoolean(1); Mockito.verify(resultSet).getBoolean(1);
@ -42,8 +65,6 @@ public class GenericDaoBaseTest {
@Test @Test
public void getObjectPrimitiveBoolean() throws SQLException { public void getObjectPrimitiveBoolean() throws SQLException {
Mockito.when(resultSet.getObject(1)).thenReturn(false);
Mockito.when(resultSet.getBoolean(1)).thenReturn(false);
Assert.assertFalse(GenericDaoBase Assert.assertFalse(GenericDaoBase
.getObject(boolean.class, resultSet, 1)); .getObject(boolean.class, resultSet, 1));
Mockito.verify(resultSet).getBoolean(1); Mockito.verify(resultSet).getBoolean(1);
@ -51,8 +72,6 @@ public class GenericDaoBaseTest {
@Test @Test
public void getObjectPrimitiveShort() throws SQLException { public void getObjectPrimitiveShort() throws SQLException {
Mockito.when(resultSet.getObject(1)).thenReturn((short) 1);
Mockito.when(resultSet.getShort(1)).thenReturn((short) 1);
Assert.assertEquals(Short.valueOf((short) 1), Assert.assertEquals(Short.valueOf((short) 1),
GenericDaoBase.getObject(short.class, resultSet, 1)); GenericDaoBase.getObject(short.class, resultSet, 1));
Mockito.verify(resultSet).getShort(1); Mockito.verify(resultSet).getShort(1);
@ -60,8 +79,6 @@ public class GenericDaoBaseTest {
@Test @Test
public void getObjectShort() throws SQLException { public void getObjectShort() throws SQLException {
Mockito.when(resultSet.getObject(1)).thenReturn((short) 1);
Mockito.when(resultSet.getShort(1)).thenReturn((short) 1);
Assert.assertEquals(Short.valueOf((short) 1), Assert.assertEquals(Short.valueOf((short) 1),
GenericDaoBase.getObject(Short.class, resultSet, 1)); GenericDaoBase.getObject(Short.class, resultSet, 1));
Mockito.verify(resultSet).getShort(1); Mockito.verify(resultSet).getShort(1);
@ -69,8 +86,6 @@ public class GenericDaoBaseTest {
@Test @Test
public void getObjectFloat() throws SQLException { public void getObjectFloat() throws SQLException {
Mockito.when(resultSet.getObject(1)).thenReturn(0.1f);
Mockito.when(resultSet.getFloat(1)).thenReturn(0.1f);
Assert.assertEquals(0.1f, Assert.assertEquals(0.1f,
GenericDaoBase.getObject(Float.class, resultSet, 1), 0.1); GenericDaoBase.getObject(Float.class, resultSet, 1), 0.1);
Mockito.verify(resultSet).getFloat(1); Mockito.verify(resultSet).getFloat(1);
@ -78,8 +93,6 @@ public class GenericDaoBaseTest {
@Test @Test
public void getObjectPrimitiveFloat() throws SQLException { public void getObjectPrimitiveFloat() throws SQLException {
Mockito.when(resultSet.getObject(1)).thenReturn(0.1f);
Mockito.when(resultSet.getFloat(1)).thenReturn(0.1f);
Assert.assertEquals(0.1f, Assert.assertEquals(0.1f,
GenericDaoBase.getObject(float.class, resultSet, 1), 0.1); GenericDaoBase.getObject(float.class, resultSet, 1), 0.1);
Mockito.verify(resultSet).getFloat(1); Mockito.verify(resultSet).getFloat(1);
@ -87,8 +100,6 @@ public class GenericDaoBaseTest {
@Test @Test
public void getObjectPrimitiveDouble() throws SQLException { public void getObjectPrimitiveDouble() throws SQLException {
Mockito.when(resultSet.getObject(1)).thenReturn(0.1d);
Mockito.when(resultSet.getDouble(1)).thenReturn(0.1d);
Assert.assertEquals(0.1d, Assert.assertEquals(0.1d,
GenericDaoBase.getObject(double.class, resultSet, 1), 0.1); GenericDaoBase.getObject(double.class, resultSet, 1), 0.1);
Mockito.verify(resultSet).getDouble(1); Mockito.verify(resultSet).getDouble(1);
@ -96,8 +107,6 @@ public class GenericDaoBaseTest {
@Test @Test
public void getObjectDouble() throws SQLException { public void getObjectDouble() throws SQLException {
Mockito.when(resultSet.getObject(1)).thenReturn(0.1d);
Mockito.when(resultSet.getDouble(1)).thenReturn(0.1d);
Assert.assertEquals(0.1d, Assert.assertEquals(0.1d,
GenericDaoBase.getObject(Double.class, resultSet, 1), 0.1); GenericDaoBase.getObject(Double.class, resultSet, 1), 0.1);
Mockito.verify(resultSet).getDouble(1); Mockito.verify(resultSet).getDouble(1);
@ -105,8 +114,6 @@ public class GenericDaoBaseTest {
@Test @Test
public void getObjectLong() throws SQLException { public void getObjectLong() throws SQLException {
Mockito.when(resultSet.getObject(1)).thenReturn(1l);
Mockito.when(resultSet.getLong(1)).thenReturn(1l);
Assert.assertEquals((Long) 1l, Assert.assertEquals((Long) 1l,
GenericDaoBase.getObject(Long.class, resultSet, 1)); GenericDaoBase.getObject(Long.class, resultSet, 1));
Mockito.verify(resultSet).getLong(1); Mockito.verify(resultSet).getLong(1);
@ -114,8 +121,6 @@ public class GenericDaoBaseTest {
@Test @Test
public void getObjectPrimitiveLong() throws SQLException { public void getObjectPrimitiveLong() throws SQLException {
Mockito.when(resultSet.getObject(1)).thenReturn(1l);
Mockito.when(resultSet.getLong(1)).thenReturn(1l);
Assert.assertEquals((Long) 1l, Assert.assertEquals((Long) 1l,
GenericDaoBase.getObject(long.class, resultSet, 1)); GenericDaoBase.getObject(long.class, resultSet, 1));
Mockito.verify(resultSet).getLong(1); Mockito.verify(resultSet).getLong(1);
@ -123,8 +128,6 @@ public class GenericDaoBaseTest {
@Test @Test
public void getObjectPrimitiveInt() throws SQLException { public void getObjectPrimitiveInt() throws SQLException {
Mockito.when(resultSet.getObject(1)).thenReturn(1l);
Mockito.when(resultSet.getInt(1)).thenReturn(1);
Assert.assertEquals((Integer) 1, Assert.assertEquals((Integer) 1,
GenericDaoBase.getObject(int.class, resultSet, 1)); GenericDaoBase.getObject(int.class, resultSet, 1));
Mockito.verify(resultSet).getInt(1); Mockito.verify(resultSet).getInt(1);
@ -132,8 +135,6 @@ public class GenericDaoBaseTest {
@Test @Test
public void getObjectInteger() throws SQLException { public void getObjectInteger() throws SQLException {
Mockito.when(resultSet.getObject(1)).thenReturn(1l);
Mockito.when(resultSet.getInt(1)).thenReturn(1);
Assert.assertEquals((Integer) 1, Assert.assertEquals((Integer) 1,
GenericDaoBase.getObject(Integer.class, resultSet, 1)); GenericDaoBase.getObject(Integer.class, resultSet, 1));
Mockito.verify(resultSet).getInt(1); Mockito.verify(resultSet).getInt(1);
@ -141,11 +142,44 @@ public class GenericDaoBaseTest {
@Test @Test
public void getObjectPrimitiveByte() throws SQLException { public void getObjectPrimitiveByte() throws SQLException {
Mockito.when(resultSet.getObject(1)).thenReturn((byte) 1);
Mockito.when(resultSet.getByte(1)).thenReturn((byte) 1);
Assert.assertTrue((byte) 1 == GenericDaoBase.getObject(byte.class, Assert.assertTrue((byte) 1 == GenericDaoBase.getObject(byte.class,
resultSet, 1)); resultSet, 1));
Mockito.verify(resultSet).getByte(1); Mockito.verify(resultSet).getByte(1);
} }
@Test
public void handleEntityExistsExceptionTestNoMatchForEntityExists() {
Mockito.when(mockedSQLException.getErrorCode()).thenReturn(123);
Mockito.when(mockedSQLException.getSQLState()).thenReturn("123");
GenericDaoBase.handleEntityExistsException(mockedSQLException);
}
@Test
public void handleEntityExistsExceptionTestIntegrityConstraint() {
Mockito.when(mockedSQLException.getErrorCode()).thenReturn(123);
Mockito.when(mockedSQLException.getSQLState()).thenReturn(INTEGRITY_CONSTRAINT_VIOLATION);
GenericDaoBase.handleEntityExistsException(mockedSQLException);
}
@Test
public void handleEntityExistsExceptionTestIntegrityConstraintNull() {
Mockito.when(mockedSQLException.getErrorCode()).thenReturn(123);
Mockito.when(mockedSQLException.getSQLState()).thenReturn(null);
GenericDaoBase.handleEntityExistsException(mockedSQLException);
}
@Test
public void handleEntityExistsExceptionTestDuplicateEntryErrorCode() {
Mockito.when(mockedSQLException.getErrorCode()).thenReturn(DUPLICATE_ENTRY_ERRO_CODE);
Mockito.when(mockedSQLException.getSQLState()).thenReturn("123");
GenericDaoBase.handleEntityExistsException(mockedSQLException);
}
@Test(expected = EntityExistsException.class)
public void handleEntityExistsExceptionTestExpectEntityExistsException() {
Mockito.when(mockedSQLException.getErrorCode()).thenReturn(DUPLICATE_ENTRY_ERRO_CODE);
Mockito.when(mockedSQLException.getSQLState()).thenReturn(INTEGRITY_CONSTRAINT_VIOLATION);
GenericDaoBase.handleEntityExistsException(mockedSQLException);
}
} }