Hello even after I perused Stack Overflow and other sites I have yet to address the problem. I would think it's a configuration issue but both persistence.xml and tomee.xml files seem perfectly fine.
The issue seems to be this line:
returnList = mapToDtoList(getEntityManager().createNativeQuery("SELECT * FROM map_category_content_type", entityClass).getResultList());
It is generating a "Column index out of range exception 0 < 1"
In most cases this is due to an errant index. But in my case, since I never reference an index directly at all (the "magic" is supposed to do that for me) I can only blame either configuration or getResultList().
I have hit a brick wall.
Here is the exception and context.
*I am not allowed to post images (not enough "reputation points") but I can assure you that the stack trace is identical to the one found here:
Getting column index out of range, 0 < 1
persistence.java code:
#Stateless
#TransactionAttribute(TransactionAttributeType.REQUIRED)
public class CategoriesAndContentTypesMapPersistence extends AbstractPersistenceService<CategoriesAndContentTypesMap, CategoriesAndContentTypesMapDto, Integer> {
public List<CategoriesAndContentTypesMapDto> getCategoriesAndContentTypes() {
List<CategoriesAndContentTypesMapDto> returnList;
try {
returnList = mapToDtoList(getEntityManager().createNativeQuery("SELECT * FROM map_category_content_type", entityClass).getResultList());
} catch (Exception e) {
System.out.println("---> "+e);
throw new PersistenceException(e, this.getClass());
}
return returnList;
}
}
The caller code:
#Inject
private CategoriesAndContentTypesMapPersistence catContPersistence;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int categoryID = 0;
String categoryName = "";
int categorySortOrder = 0;
int contentTypeID = 0;
String contentTypeName = "";
int contentTypeSortOrder = 0;
int contentTypeRequired = 0;
int contentTypeVisibility = 0;
Map<Integer, String> categoriesContentTypes = new LinkedHashMap<Integer, String>();
List<CategoriesAndContentTypesMapDto> dbCatsConts = catContPersistence.getCategoriesAndContentTypes();
for (CategoriesAndContentTypesMapDto catCotItem : dbCatsConts) {
categoryID = catCotItem.getCategoryId();
categoryName = catCotItem.getCategoryName();
categorySortOrder = catCotItem.getCategorySortOrder();
contentTypeID = catCotItem.getContentTypeId();
contentTypeName = catCotItem.getContentTypeName();
contentTypeSortOrder = catCotItem.getContentTypeSortOrder();
contentTypeRequired = catCotItem.getContentTypeRequired();
contentTypeVisibility = catCotItem.getContentTypeVisible();
I suspect my problem is something along these lines:
Getting column index out of range, 0 < 1
but the conf files look fine and were working.
Any advice is greatly appreciated.
Nevermind.
I didn't have a "managed bean" among other architectural EJB/JSF/... necessities.
Thanks all!
Related
I'd like to implement the data from Excel file to different tests depending on the scenario correct data/invalid one, however when I want to get the cell value I get the "NegativeArraySizeException".
The first row has just a title so I don't want to read it, that's why I have the parameters [rows-1].
Could you please indicate what is my mistake?
Thank you
public class SignInTest extends Driver {
#BeforeMethod
public void setUp() {
Driver.initConfiguration();
}
public Object[][] getData(String excelPath, String sheetName) {
int rows = excel.getRowCount(sheetName);
int cols = excel.getColumnCount(sheetName);
Object[][] data = new Object[rows - 1][1];
excel = new ExcelReader(excelPath);
for (int rowNum = 1; rowNum < rows; rowNum++) {
for (int colNum = 0; colNum < cols; colNum++) {
data[rowNum - 1][colNum] = excel.getCellData(sheetName, colNum, rowNum);
}
}
return data;
}
#DataProvider(name = "credentials")
public Object[][] getCredentials() {
Object[][] data = getData(excelPath, sheetName);
return data;
}
#Test(dataProviderClass = DataProviders.class, dataProvider = "credentials")
public void loginWithCorrectCredentials(String email, String password) {
HomePageActions hp = new HomePageActions();
SignInActions sign = new SignInActions();
DataProviders dp = new DataProviders();
dp.getData(excelPath, "correctData");
System.out.println("email " + email);
System.out.println("password " + password);
}
This function "excel.getRowCount(sheetName)"
On this line:
int rows = excel.getRowCount(sheetName);
Is returning 0 (or possibly null), thus when you do rows-1, you get a number less than zero. I should hope that much is obvious. So the question becomes WHY?
Things to look for in troubleshooting:
Is the getColumnCount also returning zero? If so, this points to a possible
error in the worksheet reference.
Is the sheetName actually correctly being passed into the function?
Can you insert an explicit value into a specific place on the worksheet? Meaning is that reference working? Throw in a test line and see what happens.
What happens if you hard set the array to say:
Object[][] data = new Object[100][1];
My gut is telling me you have an issue with the reference to the worksheet, but without knowing more about your worksheet referencing, it's impossible to know for sure.
I hope some of this points you in the right direction and gets you going. Good luck!
My java spring boot app needs to create a new excel file based on the contents of my DB. My current solution places all the data from my DB and inserts it in my excel sheet, but I want to improve it by not stating what the cell values are. For example, although it works, my solution has 34 fields so I am stating the userRow.createCell line 34 times for each field which is repetitive. Ideally I want to say create the cell(n) and take all the values from each row in the DB. How can this be done? Another for loop within this for loop? Every example I looked at online seems to specifically state what the cell value is.
List<CaseData> cases = (List<CaseData>) model.get("cases");
Sheet sheet = workbook.createSheet("PIE Cases");
int rowCount = 1;
for (CaseData pieCase : cases) {
Row userRow = sheet.createRow(rowCount++);
userRow.createCell(0).setCellValue(pieCase.getCaseId());
userRow.createCell(1).setCellValue(pieCase.getAcknowledgementReceivedDate());
}
Use the Reflection API
Example:
try {
Class caseDataObj = CaseData.class;
Method [] methods = caseDataObj.getDeclaredMethods();
Sheet sheet = workbook.createSheet("PIE Cases");
int rowCount = 1;
for(CaseData cd : cases) {
int cellIndex = 0;
Row userRow = sheet.createRow(rowCount++);
for (Method method : methods) {
String methodName = method.getName();
if(methodName.startsWith("get")) {
// Assuming all getters return String
userRow.createCell(cellIndex++).setCellValue((String) method.invoke(cd));
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
There are probably many ways to do this, You can try something like this, this is how I usually go about it for things like what you are doing.
public enum DATA {
CASE_ID(0),
ACK_RECIEVED(1),
ETC(2);
//ETC(3) and so on
public int index;
DATA(int index) {
this.index = index;
}
public Object parse(CaseData data) throws Exception {
switch (this) {
case CASE_ID:
return data.getCaseId();
case ACK_RECIEVED:
return data.getAcknowledgementReceivedDate();
case ETC:
return "etc...";
default: return null;
}
}
}
Then, the implementation is:
List<CaseData> cases = (List<CaseData>) model.get("cases");
Sheet sheet = workbook.createSheet("PIE Cases");
int rowCount = 1;
for (CaseData pieCase : cases) {
Row userRow = sheet.createRow(rowCount++);
for (DATA DAT : DATA.values()) {
userRow.createCell(DAT.index).setCellValue(DAT.parse(pieCase));
}
}
I have a very strange problem. I'm trying to show in a basket the price of products. When I run the code and add a product to the basket, I can see the name of the product but I can't see its price. When I click back to a previous page and add another product, I am able to see its price. There is no error message.
Also, when I try to debug this program, everything works. The problem appears only when I'm not debugging. The problem is closely connected with these two variables as indicated below. I think that these variables are 0 which is later printed on the screen. But I don't know why they are sometimes 0 and sometimes not. I also tried to set breakpoints on:
dataService.getQuantityOfDays();
dataService.getQuantityOfBreakfasts();
When I assign values to these two variables in Data class everything is ok (not 0).
Controller code:
#RequestMapping("/basket/{roomName}")
public String createBasket(Model model, #PathVariable("roomName") String roomName){
Floor currentFloor = floorService.getCurrentFloor();
User currentUser = userService.getCurrentUser();
this.roomName = roomName;
if(currentFloor != null){
Room currentRoom = roomService.getRoomByName(roomName, currentFloor);
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String name = auth.getName();
if(currentUser == null){
userService.setCurrentUser(userService.getUserByName(name)); // wykona sie jesli nie zakladamy konta w danej sesji
}
Basket basketToSave = new Basket(userService.getCurrentUser());
BasketItem basketItem = new BasketItem(currentRoom);
int quantityOfDays = dataService.getQuantityOfDays(); //<--problem
int quantityOfBreakfast = dataService.getQuantityOfBreakfasts(); //<--problem
int priceForOneBreakfast = 17;
int priceForOneDay = currentRoom.getPriceForOneDay();
int wholePrice = quantityOfDays * priceForOneDay + quantityOfBreakfast * priceForOneBreakfast;
basketItem.setPrice(wholePrice);
basketItem.setQuantityOfDays(quantityOfDays);
basketItem.setQuantityOfBreakfast(quantityOfBreakfast);
Set<BasketItem> basketItemList = new HashSet<BasketItem>();
basketItemList.add(basketItem);
basketService.countBasketPrice(basketItemList, basketToSave);
basketToSave.setBasketItems(basketItemList);
basketItem.setBasket(basketToSave);
currentRoom.setBasketItemList(basketItemList);
boolean ifWasAnUpdate = basketService.save(basketToSave); // metoda save oprócz zapisu lub nadpisania zwraca co się wydarzyło (true - jesli nadpisywaliśmy koszyk)
if(ifWasAnUpdate){
basketItem.setBasket(basketService.get(basketToSave.getUser())); // jeżeli dodaje coś do koszyka (a nie tworzę go od nowa), muszę ustawić basketItemowi
} // koszyk, który już istnieje, a nie ten, który stworzyłem wcześniej w klasie BasketController.
// W tym celu pobieram go z bazy.
basketItemService.save(basketItem);
}
model.addAttribute("basket", basketService.get(currentUser));
model.addAttribute("days", dataService.getQuantityOfDays());
return "basket";
}
EDIT:
It's a repository code.
#Repository
public class DataRepositoryImpl implements DataRepository {
private int quantityOfDays;
private int quantityOfBreakfasts;
public void setQuantityOfDaysAndBreakfasts(String text) {
List<Integer> listOfIndexes = new ArrayList<Integer>();
for(int i=0;i<text.length();i++){
if(text.charAt(i) != '1'){
listOfIndexes.add(i);
}
}
char znak = text.charAt(listOfIndexes.get(0));
this.quantityOfDays = Character.getNumericValue(text.charAt(listOfIndexes.get(0))); // <- I put breakpoint here
this.quantityOfBreakfasts = Character.getNumericValue(text.charAt(listOfIndexes.get(1))); // <- I put breakpoint here
}
public int getQuantityOfDays() {
return this.quantityOfDays;
}
public int getQuantityOfBreakfasts() {
return this.quantityOfBreakfasts;
}
}
A problem can be also in basket save. Firslty when I can see only zeros I persist basket, then I'm only updating it.
Save & update methods:
public boolean save(Basket basketToSave) {
List<Basket> listOfAllBaskets = getAll();
boolean save = true;
boolean ifWasAnUpdate = false;
for(Basket basket: listOfAllBaskets){
if(basketToSave.getUser().equals(basket.getUser())){
save = false;
}
}
if(save){
emManager.persist(basketToSave);
}else{
updateBasket(basketToSave);
ifWasAnUpdate = true;
}
return ifWasAnUpdate;
}
public void updateBasket(Basket basket) {
Basket basketFromDatabase = get(basket.getUser());
basketFromDatabase.setBasketItems(basket.getBasketItems());
basketFromDatabase.setPrice(basket.getPrice());
emManager.merge(basketFromDatabase);
}
EDIT
I'm calling setQuantityOfDaysAndBreakfasts(text) earlier in this apllication. In this controller I'm only setting these values to basketItem class. I'll change this controller. Here another controller where I call setQuantityOfDaysAndBreakfasts(text).
#RequestMapping(value = "/room/rest", method = RequestMethod.POST, consumes = {"application/json"})
public void data(#RequestBody Data request){
String text = request.getText();
dataService.setQuantityOfDaysAndBreakfasts(text);
}
You are calling setQuantityOfDaysAndBreakfasts() after you get the value from your dataService. The value for quantityOfDays and quantityOfBreakfasts are only set when that method is called.
There are several things you should also examine.
As #NathanHughes points out, it's best to put your complex logic in your service layer and leave the controller to simply route requests. This is also true of your repository class. You should keep this very simple as the next developer reading your code is not going to expect to find any logic that doesn't simply read or write to your data source. (See Single Responsibility Principle.) It will also reduce code duplication in the future and as a result, reduce your time maintaining and fixing bugs.
For example, this code:
List<Integer> listOfIndexes = new ArrayList<Integer>();
for(int i=0;i<text.length();i++){
if(text.charAt(i) != '1'){
listOfIndexes.add(i);
}
}
char znak = text.charAt(listOfIndexes.get(0));
Should be refactored to a separate method entirely that can be made static and would not belong in that class.
OK this is going to be a bit long and complex, I'm hoping for some rubber ducking here.
I have this code, which is actually a bit more complex, but I think i did a reasonable job of simplifying it:
private Result getResult(Request request, RequestType type) {
final String date = request.getData(); // marker 1
final DataSource jdbcDataSource = getDataSource();
final JdbcOperations jdbcTemplate = newJdbcOperations(jdbcDataSource);
final TransactionTemplate transactionTemplate = createTransactionTemplate(jdbcDataSource);
Supplier<Integer> createResult = () -> transactionTemplate.execute(transactionStatus -> {
List<Map<String, Object>> rs = jdbcTemplate.queryForList("SELECT * FROM table");
if (rs.size() > 0) {
return ((Number) rs.get(0).get("count")).intValue();
} else {
log.info(request + " not found in table");
}
if (type == TYPE1) {
//...
} else {
throw new RuntimeException("unexpected type:" + type); // marker2
}
return 0;
});
int retryCount = 0;
while (retryCount < 5) {
try {
totalCount = createResult.get();
break;
} catch (DuplicateKeyException | DeadlockLoserDataAccessException e) {
// log
}
retryCount++;
}
}
This works fine, except that today the app server got into a state where it stopped working. The method enters, gets past line "marker1" so we know request is not null, then proceeds to log "null not found in table" suggesting that request turned into null and then throws runtimeException "marker2" because type has turned into null as well.
I hate to say it but this really just smells like a bug in JVM, but this really should be the last to consider, so I'm hoping that you, my dear rubber duck, would have some ideas.
OK, I have a JSP running the following script section.
<% irCollection mgrq = new irCollection();
mgrq.setMgrid("Chris Novish");
mgrq.populateCollection();
int pagenum;
if (request.getParameter("p") != null) {
String pagedatum=request.getParameter("p");
pagenum = Integer.parseInt(pagedatum);
} else { pagenum = 0; }
for (int i=0;i<10;i++) {
int rownum = pagenum * 10 + i;
InquireRecord currec = mgrq.getCurRecords(rownum);
out.println(currec.getID()); %>
irCollection has an ArrayList property that stores a several InquireRecord objects. It gets this data from a database using the mgrid as (set in line 2 there) as the matching term.
But I'm getting an IndexOutOfBounds exception on what appears here as line 11.
I've done some tests, and I'm pretty sure that it's because populateCollection() isn't getting things done. I have a getSize method that gives me a size of 0.
I made a test class in Eclipse to make sure all my methods were working:
package com.serco.inquire;
public class test {
public static void main (String[] args) {
String mgr = "Chris Novish";
irCollection bob = new irCollection();
bob.setMgrid(mgr);
bob.populateCollection();
InquireRecord fred = bob.getCurRecords(1);
System.out.println(fred.getID());
}
}
That test class produces exactly what I'd expect.
Other than the names of some of the local variables, I can't see what I'm doign different in the JSP.
So... tell me, what noobish mistake did I make?
for the sake of being thorough, here's the populateCollection() method:
public void populateCollection() {
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String filename = "inquire.mdb";
String database = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=";
database+= filename.trim() + ";DriverID=22;READONLY=true}";
Connection con = DriverManager.getConnection( database ,"","");
Statement s = con.createStatement();
s.execute ("SELECT * FROM inquiries WHERE manager = '" + mgrid + "'");
ResultSet rs = s.getResultSet();
int cur;
if (rs != null) {
while (rs.next()) {
cur = rs.getRow();
cur -- ;
int curID = rs.getInt("ID");
this.newIR.setID(curID);
String cursub = rs.getString("submitter");
this.newIR.setSubmitter(cursub);
this.iRecords.add(cur, this.newIR);
}
this.size = iRecords.size();
this.pages = this.size / 10;
int remain = this.size % 10;
if (remain > 0) { this.pages++; }
} else { System.out.println("no records."); }
}
catch (Throwable e) {
System.out.println(e);
}
}
Your IndexOutOfBounds exception is probably being caused by the value of rownum being passed to mgrq.getCurRecords().
Your test code proves nothing because there you're calling getCurRecords() with a constant which is probably always valid for your system and will never cause the exception.
My suggestion is to step through the code in your JSP with a debugger, or even simply to print out the value of your variables (especially pagedatum, pagenum and rownum) in your JSP code.
Is your JSP Snippet correct? It looks like you started the braces for the
for (int i=0;i<10;i++) {
but I dont see a end braces for that at all. Can you check if that is the case and if so, fix the code appropriately?