I saw questions about GWT + SPRING + HIBERNATE integration but none is clear or up to date with the current versions!
Please if there is anyone who has a clear and simple example of the integration (form submit and saving in DB) I will be extremely thankful!
If you could put the simple project in a ZIP and upload it (with its jars it will be great)
Thank you!
I guess this one using gwt 2.5.0-rc1, Spring 3.1.2.RELEASE and Hibernate 4 will be helpful. This project is using maven, so install maven which will take care of required dependencies. git clone it, command-line build with $ mvn clean install and dive into.
The basic gwt server-shared-client architecture is
Entity
#Entity
#Table(name = "TBL_BOOK")
public class Book implements Serializable {
private static final long serialVersionUID = -687874117917352477L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "ID")
private Long id;
#Column(name = "TITLE", nullable = false)
private String title;
#Column(name = "SUBTITLE")
private String subtitle;
#Column(name = "AUTOR", nullable = false)
private String autor;
#Column(name = "DESCRIPTION")
private String description;
#Column(name = "ISBN")
private String isbn;
#Column(name = "GENRE")
private String genre;
#Temporal(TemporalType.DATE)
#Column(name = "PUBLISHED_DATE")
private Date publishedDate;
#Column(name = "PUBLISHER")
private String publisher;
public Book() {
}
public Book(Long id, String title, String subtitle, String autor,
String description, String isbn, String genre, Date publishedDate,
String publisher) {
this.id = id;
this.title = title;
this.subtitle = subtitle;
this.autor = autor;
this.description = description;
this.isbn = isbn;
this.genre = genre;
this.publishedDate = publishedDate;
this.publisher = publisher;
}
public Book(Book bookDTO) {
this.id = bookDTO.getId();
this.title = bookDTO.getTitle();
this.subtitle = bookDTO.getSubtitle();
this.autor = bookDTO.getAutor();
this.description = bookDTO.getDescription();
this.isbn = bookDTO.getIsbn();
this.genre = bookDTO.getGenre();
this.publishedDate = bookDTO.getPublishedDate();
this.publisher = bookDTO.getPublisher();
}
//getters and setters
#Override
public String toString() {
return "Book [id=" + id + ", title=" + title + ", subtitle=" + subtitle
+ ", author=" + autor + ", description=" + description
+ ", isbn=" + isbn + ", genre=" + genre + ", publishedDate="
+ publishedDate + ", publisher=" + publisher + "]";
}
}
web configuration
<!-- SpringGwt remote service servlet -->
<servlet>
<servlet-name>springGwtRemoteServiceServlet</servlet-name>
<servlet-class>org.spring4gwt.server.SpringGwtRemoteServiceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springGwtRemoteServiceServlet</servlet-name>
<url-pattern>/GwtSpringHibernate/springGwtServices/*</url-pattern>
</servlet-mapping>
Client side stub for RPC
/**
* The client side stub for the RPC service.
*/
#RemoteServiceRelativePath("springGwtServices/bookService")
public interface BookService extends RemoteService {
public void saveOrUpdate(Book book) throws Exception;
public void delete(Book book) throws Exception;
public Book find(long id);
public List<Book> findAllEntries();
}
Server
#Service("bookService")
public class BookServiceImpl extends RemoteServiceServlet implements BookService {
private static final long serialVersionUID = -6547737229424190373L;
private static final Log LOG = LogFactory.getLog(BookServiceImpl.class);
#Autowired
private BookDAO bookDAO;
#Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public void saveOrUpdate(Book book) throws Exception {
//
}
#Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public void delete(Book book) throws Exception {
//
}
public Book find(long id) {
return bookDAO.findById(id);
}
public List<Book> findAllEntries() {
//
}
}
Client View
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class GwtSpringHibernate implements EntryPoint {
/**
* The message displayed to the user when the server cannot be reached or
* returns an error.
*/
private static final String SERVER_ERROR = "An error occurred while "
+ "attempting to contact the server. Please check your network "
+ "connection and try again.";
/**
* Create a remote service proxy to talk to the server-side Book service.
*/
private final BookServiceAsync bookService = GWT.create(BookService.class);
/**
* This is the entry point method.
*/
public void onModuleLoad() {
DateBox.DefaultFormat defaultFormatter = new DateBox.DefaultFormat(DateTimeFormat.getFormat("dd.MM.yyyy"));
// Add new Book Area
final TextBox titleField = new TextBox();
titleField.setFocus(true);
final TextBox subtitleField = new TextBox();
final TextBox autorField = new TextBox();
final TextBox descriptionField = new TextBox();
final TextBox isbnField = new TextBox();
final TextBox genreField = new TextBox();
final DateBox publishedDateField = new DateBox();
publishedDateField.setFormat(defaultFormatter);
final TextBox publisherField = new TextBox();
final Button saveButton = new Button("Save");
saveButton.addStyleName("button");
final Button retrieveButton = new Button("Retrieve");
retrieveButton.addStyleName("button");
final Label errorLabel = new Label();
// Add fields to the Rootpanel
RootPanel.get("title").add(titleField);
RootPanel.get("subtitle").add(subtitleField);
RootPanel.get("autor").add(autorField);
RootPanel.get("description").add(descriptionField);
RootPanel.get("isbn").add(isbnField);
RootPanel.get("genre").add(genreField);
RootPanel.get("publishedDate").add(publishedDateField);
RootPanel.get("publisher").add(publisherField);
RootPanel.get("btnSave").add(saveButton);
RootPanel.get("btnRetrieveAllEntries").add(retrieveButton);
RootPanel.get("errorLabelContainer").add(errorLabel);
// Create the popup dialog box
final DialogBox dialogBox = new DialogBox();
dialogBox.setText("Remote Procedure Call");
dialogBox.setAnimationEnabled(true);
final Button closeButton = new Button("Close");
// We can set the id of a widget by accessing its Element
closeButton.getElement().setId("closeButton");
final Label textToServerLabel = new Label();
final HTML serverResponseLabel = new HTML();
VerticalPanel dialogVPanel = new VerticalPanel();
dialogVPanel.addStyleName("dialogVPanel");
dialogVPanel.add(new HTML("<b>Sending request to the server:</b>"));
dialogVPanel.add(textToServerLabel);
dialogVPanel.add(new HTML("<b>Server replies:</b>"));
dialogVPanel.add(serverResponseLabel);
dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);
dialogVPanel.add(closeButton);
dialogBox.setWidget(dialogVPanel);
// Add a handler to close the DialogBox
closeButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
dialogBox.hide();
saveButton.setEnabled(true);
saveButton.setFocus(true);
retrieveButton.setEnabled(true);
}
});
class SaveBookHandler implements ClickHandler, KeyUpHandler {
public void onKeyUp(KeyUpEvent event) {
if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
saveBook();
}
}
public void onClick(ClickEvent arg0) {
saveBook();
}
private void saveBook() {
errorLabel.setText("");
String _title = titleField.getText();
String _subtitle = subtitleField.getText();
String _autor = autorField.getText();
String _desc = descriptionField.getText();
String _isbn = isbnField.getText();
String _genre = genreField.getText();
Date _publishedDate = publishedDateField.getValue();
String _publisher = publisherField.getText();
// First, we validate the input.
if (Validator.isBlank(_title) || Validator.isBlank(_autor)) {
String errorMessage = "Please enter at least the Title and the Autor of the book";
errorLabel.setText(errorMessage);
return;
}
Book bookDTO = new Book(null, _title, _subtitle, _autor, _desc, _isbn, _genre, _publishedDate, _publisher);
saveButton.setEnabled(false);
serverResponseLabel.setText("");
textToServerLabel.setText(bookDTO.toString());
bookService.saveOrUpdate(bookDTO, new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
dialogBox.setText("Remote Procedure Call - Failure");
serverResponseLabel.addStyleName("serverResponseLabelError");
serverResponseLabel.setHTML(SERVER_ERROR + caught.toString());
dialogBox.center();
closeButton.setFocus(true);
}
public void onSuccess(Void noAnswer) {
dialogBox.setText("Remote Procedure Call");
serverResponseLabel.removeStyleName("serverResponseLabelError");
serverResponseLabel.setHTML("OK");
dialogBox.center();
closeButton.setFocus(true);
}
});
}
}
// Add a handler to send the book info to the server
SaveBookHandler saveBookHandler = new SaveBookHandler();
saveButton.addClickHandler(saveBookHandler);
publisherField.addKeyUpHandler(saveBookHandler);
// Create a handler for the retrieveButton
class RetrieveAllEntriesHandler implements ClickHandler {
/**
* Fired when the user clicks on the retrieveButton.
*/
public void onClick(ClickEvent event) {
retrieveAllEntries();
}
private void retrieveAllEntries() {
// Nothing to validate here
// Then, we send the input to the server.
retrieveButton.setEnabled(false);
errorLabel.setText("");
textToServerLabel.setText("");
serverResponseLabel.setText("");
bookService.findAllEntries(
new AsyncCallback<List<Book>>() {
public void onFailure(Throwable caught) {
// Show the RPC error message to the user
dialogBox.setText("Remote Procedure Call - Failure");
serverResponseLabel.addStyleName("serverResponseLabelError");
serverResponseLabel.setHTML(SERVER_ERROR + caught.toString());
dialogBox.center();
closeButton.setFocus(true);
}
public void onSuccess(List<Book> data) {
dialogBox.setText("Remote Procedure Call");
serverResponseLabel.removeStyleName("serverResponseLabelError");
if(data != null && !data.isEmpty()){
StringBuffer buffer = new StringBuffer();
for (Book book : data) {
buffer.append(book.toString());
buffer.append("<br /><br />");
}
serverResponseLabel.setHTML(buffer.toString());
} else {
serverResponseLabel.setHTML("No book information store in the database.");
}
dialogBox.center();
closeButton.setFocus(true);
}
});
}
}
// Add a handler
RetrieveAllEntriesHandler retrieveAllEntriesHandler = new RetrieveAllEntriesHandler();
retrieveButton.addClickHandler(retrieveAllEntriesHandler);
}
}
For more widgets, go through official widget library, UiBinder.
1) Download the zip file cited above from https://github.com/chieukam/gwt-spring-hibernate-tutorial/archive/master.zip and extract it somewhere
2) In Eclipse, create a new Maven project. Since there is no .project file provided in the above zip, you will need to confiugre all this manually.
3) Import "File System" from the place where you unzipped this project into your new Maven project.
At this point, I have some errors:
BookServiceAsync appears to be nonexistent, resulting in 6 compile errors.
"Plugin execution not covered by lifecycle configuration: org.apache.maven.plugins:maven-war-plugin:2.1.1:exploded (execution: default, phase: compile)" in pom.xml, lines 162 and 185
This example seems to be somewhat incomplete. Am I missing something??
Related
Etity
#Entity
public class DateFMail {
#Id
private double balance;
public DateFMail() {
}
public DateFMail(double balance) {this.balance = balance;}
public DateFMail(DateFMail dateFMail) {
}
public double getBalance() { return balance;}
#Override
public String toString() {
return "DateFMail{" +
"balance=" + balance +
'}';
}
}
Service
public interface DateFMailService {
List<DateFMail> findAll();
}
Impl
#Service
public class DateFMailServiceImpl implements DateFMailService {
#Autowired
private DateFMailRepository mailRepository;
#Override
public List<DateFMail> findAll() {
return mailRepository.findAll();
}
}
Repository
#Repository
public interface DateFMailRepository extends JpaRepository<DateFMail, Long> {
#Query(value = "SELECT SUM(balance) \n" +
" FROM agents", nativeQuery = true)
List<DateFMail> findAll();
}
Mail Seder
#Service
public class EmailDos {
#Autowired
private JavaMailSender mailSender;
private DateFMailRepository mailRepository;
String fileDate1 = new SimpleDateFormat("dd.MM.yyyy").format(new Date());
LocalDate today = LocalDate.now();
String fileDate = (today.minusDays(1)).format(DateTimeFormatter.ofPattern("dd MMM"));
String fileDate2 = (today.minusMonths(1)).format(DateTimeFormatter.ofPattern("MMM"));
public void sendMailSum(String from, String to, String subject, String body, String fileToAttach) throws SQLException {
List<DateFMail> list = new ArrayList<>(mailRepository.findAll());
List<DateFMail> list1 = list.stream()
.map(DateFMail::new)
.collect(Collectors.toList());
System.out.println("sending email...................");
System.out.println(list1);
MimeMessagePreparator preparator = new MimeMessagePreparator() {
public void prepare(MimeMessage mimeMessage) throws Exception {
mimeMessage.setFrom(new InternetAddress(from));
mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
mimeMessage.setSubject(subject);
mimeMessage.setText(body);
FileSystemResource file = new FileSystemResource(new File("C:...xlsx"));
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
helper.setFrom("SomeAddress#gmail.com");
helper.setTo(InternetAddress.parse("SomeAddress#gmail.com"));
helper.setText("Good day!\nIn attachment payments for " + fileDate + " с 12.00-00.00" + "\nAmount for " + fileDate1 + list1);
helper.addAttachment("...xlsx", file);
mailSender.send(mimeMessage);
System.out.println("email Fab was successfully sent.....");
}
};
try {
mailSender.send(preparator);
} catch (MailException ex) {
System.err.println(ex.getMessage());
}
}
}
Controller
#Component
public class DateFMailController {
#Autowired
private DateFMailService mailService;
public void saveSum() throws IOException {
saveExcel(mailService.findAll(), "....xlsx");
}
private void saveExcel(List<DateFMail> list, String fileName) throws IOException {
Workbook workbook = new XSSFWorkbook();
CreationHelper createHelper = workbook.getCreationHelper();
Sheet sheet = workbook.createSheet("ECards");
sheet.autoSizeColumn(0);
Row header = sheet.createRow(0);
CellStyle headerStyle = workbook.createCellStyle();
headerStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());
headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
XSSFFont font = ((XSSFWorkbook) workbook).createFont();
font.setFontName("Arial");
font.setFontHeightInPoints((short) 10);
font.setBold(true);
headerStyle.setFont(font);
Cell headerCell = header.createCell(0);
headerCell.setCellValue("Sum");
headerCell.setCellStyle(headerStyle);
CellStyle style = workbook.createCellStyle();
style.setWrapText(true);
int ix_row=2;
for (DateFMail dateFMail : list) {
Row row = sheet.createRow(ix_row);
Cell cell = row.createCell(0);
cell.setCellValue(dateFMail.getBalance());
cell.setCellStyle(style);
ix_row++;
}
FileOutputStream outputStream = new FileOutputStream(fileName);
workbook.write(outputStream);
workbook.close();
}
}
Save Runer
#Component
public class SaveCardsStartupRunner implements ApplicationRunner {
#Autowired
private ECardController eCardController;
private DateFMailController controller;
// #Autowired
// private EmailDos emailDos;
String fileDate1 = new SimpleDateFormat("dd.MM.yyyy").format(new Date());
LocalDate today = LocalDate.now();
String fileDate = (today.minusDays(1)).format(DateTimeFormatter.ofPattern("dd MMM"));
String fileDate2 = (today.minusMonths(1)).format(DateTimeFormatter.ofPattern("MMM"));
#Override
public void run(ApplicationArguments args) throws Exception {
eCardController.saveCards();
controller.saveSum();
}
}
I have corrected my question. I've pasted all the code here that pertains to my question. For starters, I would like to simply output the Query result of the repository to the console. But in the form that I just posted here, I get a NullPointerException error and says that in a part of the code: controller.saveSum (); - controller = null.
Create a PaymentService class which should contain the method getTotalPayment. Inject this class in EmailSend (tip: please change this class name from EmailSend to EmailSender as class names should be noun) class. And then in PaymentService Class you should interact Data Repository class. Call this getTotalPayment method from the EmailSend class.
I am trying to create a service which fetch image of a student along with other text details of student stored in database and display it on an html page. I tried but some hash value is being returned.
My Model Class
#Entity
#Table(name = "details")
public class Student {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "name")
private String name;
#Column(name = "pic" , length = 2000)
private byte[] pic;
public Student(long id, String name, byte[] pic) {
super();
this.id = id;
this.name = name;
this.pic = pic;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public byte[] getPic() {
return pic;
}
public void setPic(byte[] pic) {
this.pic = pic;
}
#Override
public String toString() {
return "Student [id=" + id + ", name=" + name + "];
}
}
Without Using a rest contoller will it be achieved like this?
My Controller
#Controller
public class ImgShowController {
#Autowired
EntityRepository entityRepository;
#RequestMapping("/list")
public String getAllStudents(Model model) {
List<Imge> list = (List<Imge>) entityRepository.findAll();
model.addAttribute("students", list);
return "liststudents";
}
#RequestMapping(path= {"/particularlist","/particularlist/{id}"})
public String getImage(#PathVariable("id") Long id, Model model) {
final Optional<Student> imget = entityRepository.findById(id);
Imge imge = new Imge(imget.get().getId(), imget.get().getName(), decompressBytes(imget.get().getPic()));
model.addAttribute("particularStudent", imge);
return "particularstudent";
}
}
Decompress Byte function
public static byte[] decompressBytes(byte[] data) {
Inflater inflater = new Inflater();
inflater.setInput(data);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
byte[] buffer = new byte[1024];
try {
while (!inflater.finished()) {
int count = inflater.inflate(buffer);
outputStream.write(buffer, 0, count);
}
outputStream.close();
} catch (IOException ioe) {
} catch (DataFormatException e) {
}
return outputStream.toByteArray();
}
First of all, I would suggest mentioning that you store binary object (LOB) in pic column in your entity class:
#Lob
#Column(name = "pic" , length = 2000)
private byte[] pic;
And then, it seems that Thymeleaf does not allow you to inject image directly into model, so you have 2 ways to accomplish this:
1.Adding another controller to serve you images
#GetMapping("/students/{id}/image")
public void studentImage(#PathVariable String id, HttpServletResponse response) throws IOException {
var student = entityRepository.findById(id);
var imageDecompressed = decompressBytes(student.get().getPic());
response.setContentType("image/jpeg");
InputStream is = new ByteArrayInputStream(imageDecompressed);
IOUtils(is, response.getOutputStream());
}
and then referring to it from model like this:
<img th:src="#{'students/' + #{studentId} + '/image'}">
2.Using base64
You need to encode image as base64 string:
var base64EncodedImage = Base64.getEncoder().encodeToString(imageData);
and then setting into model like this:
<img th:src="#{'data:image/jpeg;base64,'+${base64EncodedImage}}"/>
I would suggest using the first way because otherwise you would depend on image size and overall payload would be 30% larger (base64), so by using the first way you let user's browser decide how and when to load particular image
In my spring boot project I created a Repository interface (which extends CRUDRepository) and an Entity class of the Table in my DB.
This is my Repo:
#Repository
public interface AuthPaymentDao extends CrudRepository<TFraudCard,String> {
#Query("SELECT t FROM TFraudCard t where t.tokenNumber = (?1)")
TFraudCard findByTokenNumber(String tokenNumber);
}
This is my Entity Class (TOKEN_NUMBER is the primary Key in the TFRAUDCARD TABLE):
#Entity
#Table(name = "TFRAUDCARD")
public class TFraudCard {
#Id
#Column(name="TOKEN_NUMBER")
private String tokenNumber;
#Column(name="TRANSACTIONNUMBER")
private int transactionNumber;
#Column(name="CARDNUMBER")
private int cardNumber;
#Column(name="DATEADDED", insertable = false, updatable = false, nullable = false)
private Timestamp dateAdded;
#Column(name="CALLINGENTITY", nullable = false)
private String callingEntity;
#Column(name="ACCOUNTID")
private String accountId;
#Column(name="ROUTINGNUMBER")
private String routingNumber;
#Column(name="BANKACCOUNTNUMBER")
private String bankAccountNumber;
#Column(name="COMMENTS")
private String comments;
#Column(name="USERID")
private String userId;
#Column(name="REMOVEDATE")
private Timestamp removeDate;
public String getTokenNumber() {
return tokenNumber;
}
public void setTokenNumber(String tokenNumber) {
this.tokenNumber = tokenNumber;
}
public int getTransactionNumber() {
return transactionNumber;
}
public void setTransactionNumber(int transactionNumber) {
this.transactionNumber = transactionNumber;
}
public int getCardNumber() {
return cardNumber;
}
public void setCardNumber(int cardNumber) {
this.cardNumber = cardNumber;
}
public Timestamp getDateAdded() {
return dateAdded;
}
public void setDateAdded(Timestamp dateAdded) {
this.dateAdded = dateAdded;
}
public String getCallingEntity() {
return callingEntity;
}
public void setCallingEntity(String callingEntity) {
this.callingEntity = callingEntity;
}
public String getAccountId() {
return accountId;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public String getRoutingNumber() {
return routingNumber;
}
public void setRoutingNumber(String routingNumber) {
this.routingNumber = routingNumber;
}
public String getBankAccountNumber() {
return bankAccountNumber;
}
public void setBankAccountNumber(String bankAccountNumber) {
this.bankAccountNumber = bankAccountNumber;
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public Timestamp getRemoveDate() {
return removeDate;
}
public void setRemoveDate(Timestamp removeDate) {
this.removeDate = removeDate;
}
public TFraudCard() {
super();
}
public TFraudCard(String tokenNumber, int transactionNumber, int cardNumber, Timestamp dateAdded,
String callingEntity, String accountId, String routingNumber, String bankAccountNumber, String comments,
String userId, Timestamp removeDate) {
super();
this.tokenNumber = tokenNumber;
this.transactionNumber = transactionNumber;
this.cardNumber = cardNumber;
this.dateAdded = dateAdded;
this.callingEntity = callingEntity;
this.accountId = accountId;
this.routingNumber = routingNumber;
this.bankAccountNumber = bankAccountNumber;
this.comments = comments;
this.userId = userId;
this.removeDate = removeDate;
}
#Override
public String toString() {
return "TFraudCard [tokenNumber=" + tokenNumber + ", transactionNumber=" + transactionNumber + ", cardNumber="
+ cardNumber + ", dateAdded=" + dateAdded + ", callingEntity=" + callingEntity + ", accountId="
+ accountId + ", routingNumber=" + routingNumber + ", bankAccountNumber=" + bankAccountNumber
+ ", comments=" + comments + ", userId=" + userId + ", removeDate=" + removeDate + "]";
}
}
My Service Class:
Autowiring the DAO instance inside my Service Class:
Implementing the DAO instance inside a Method in the Service Class:
private void fraudCheck(PaymentDetail paymentDetail) throws RegularPaymentBusinessException {
logger.info("INSIDE FRAUD CHECK METHOD");
String pmtInd=paymentDetail.getPmtInd();
logger.info("pmtInd: " + pmtInd);
String tokenizedCardNum=paymentDetail.getTokenizedCardNum();
logger.info("tokenizedCardNum: " + tokenizedCardNum);
if(pmtInd.equalsIgnoreCase(VepsConstants.GIFT_CARD_IDENTIFIER) || pmtInd.equalsIgnoreCase(VepsConstants.CREDIT_CARD_IDENTIFIER) || pmtInd.equalsIgnoreCase(VepsConstants.DEBIT_CARD_IDENTIFIER)) {
logger.info("INSIDE CARD CHECK");
TFraudCard fraudCard = authPaymentDao.findByTokenNumber(tokenizedCardNum);
logger.info("fraudCard Details: " + fraudCard.toString());
if(fraudCard!=null) {
logger.info("INSIDE EXCEPTION FLOW FOR CARD FRAUD CHECK");
throw new RegularPaymentBusinessException(VepsConstants._9966, VepsConstants._9966_MESSAGE, VepsConstants.FAILURE);
}
}
}
Even though I pass the same token Number (tokenizedCardNumber) in my method as the data in the TOKEN_NUMBER column of my TFRAUDCARD table I still get a NullPointerException when I try to print a toString() of the Entity Object.
Here is the NullPointerException on my cloudFoundry logs (Click on it to see zoomed image) :
I'm providing the DB details in my dev properties file:
I have gone over every scenario in my head for why it breaks but I still can't come up with an answer. I'm using my variable marked with #Id i.e. the Primary Key for my find() method in the Repository.
I'm also adding a #Query annotation just to be even more specific.
It still does not work.
I have BeanItemContainer, which i load from database via jdbc:
BeanItemContainer myBeans = new BeanItemContainer<>(MyBean.class, mybeanDao.findAll());
and this is how i attach it to combobox:
Combobox combo = new Combobox();
combobox.setContainerDataSource(myBeans);
So far, so good. I received what i want, but for now i have a problem -
How do i get actual id that has been selected? This must be synchronized (id selected in combobox is actual entry in database).
I have no idea, how to solve this problem
Please help
P.S MyBean class
public class MyBean {
private Long id;
private String field1;
*** getters /setters ***
and toString() {} method
}
Here is the code:
#Theme("mytheme")
public class MyUI extends UI {
#Override
protected void init(VaadinRequest vaadinRequest) {
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
layout.setSpacing(true);
setContent(layout);
BeanItemContainer myBeans = new BeanItemContainer<>(MyBean.class, getBeans());
ComboBox combo = new ComboBox();
combo.setContainerDataSource(myBeans);
combo.setItemCaptionMode(AbstractSelect.ItemCaptionMode.PROPERTY);
combo.setItemCaptionPropertyId("field");
combo.addValueChangeListener(new Property.ValueChangeListener() {
#Override
public void valueChange(Property.ValueChangeEvent event) {
MyBean bean = (MyBean) combo.getValue();
Notification notif = new Notification("Selected Bean Id: "+bean.getId(), Notification.Type.TRAY_NOTIFICATION);
notif.setPosition(Position.TOP_CENTER);
notif.show(Page.getCurrent());
}
});
layout.addComponent(combo);
}
#WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true)
#VaadinServletConfiguration(ui = MyUI.class, productionMode = false)
public static class MyUIServlet extends VaadinServlet {
}
public class MyBean {
private Long id;
private String field;
public MyBean(Long id, String field) {
this.id = id;
this.field = field;
}
public Long getId() {
return id;
}
public String getField() {
return field;
}
}
public ArrayList<MyBean> getBeans() {
ArrayList<MyBean> beans = new ArrayList<>();
MyBean bean = new MyBean(1l, "Vikrant");
beans.add(bean);
bean = new MyBean(2l, "Rampal");
beans.add(bean);
bean = new MyBean(3l, "viky");
beans.add(bean);
return beans;
}
}
If I understood the question correctly combo.getValue() should give you the MyBean instance relative to the current selection (or null if no item is selected)
I'm developing a spring boot project which uses spring batch scheduler to read data after 2 sec's and send it to the message broker (Activemq) which works fine with hardcoded fixed delay.
However, i'm now trying to read the #Scheduled(fixedDelay) from database rather hard coded but looks like nothing is working out. I can see the expression contains 10 secs but scheduler doesn't start
#Service
public class QuoteService implements ApplicationListener<BrokerAvailabilityEvent> {
private static Log logger = LogFactory.getLog(QuoteService.class);
private final MessageSendingOperations<String> messagingTemplate;
private final StockQuoteGenerator quoteGenerator = new StockQuoteGenerator();
private AtomicBoolean brokerAvailable = new AtomicBoolean();
private ReadCronExpressionDataService readCronExpressionDataService;
private int expression;
#Autowired
public QuoteService(MessageSendingOperations<String> messagingTemplate,ReadCronExpressionDataService readCronExpressionDataService) {
this.messagingTemplate = messagingTemplate;
this.readCronExpressionDataService=readCronExpressionDataService;
expression = readCronExpressionDataService.readData();
}
#Scheduled(fixedDelay=expression) //#Scheduled(fixedDelay=2000)
public void sendQuotes() {
for (Quote quote : this.quoteGenerator.generateQuotes()) {
if (logger.isTraceEnabled()) {
logger.trace("Sending quote " + quote);
}
if (this.brokerAvailable.get()) {
this.messagingTemplate.convertAndSend("/topic/price.stock." + quote.getTicker(), quote);
}
}
}
private static class StockQuoteGenerator {
private static final MathContext mathContext = new MathContext(2);
private final Random random = new Random();
private final Map<String, String> prices = new ConcurrentHashMap<>();
public StockQuoteGenerator() {
this.prices.put("CTXS", "24.30");
this.prices.put("DELL", "13.03");
this.prices.put("EMC", "24.13");
this.prices.put("GOOG", "893.49");
this.prices.put("MSFT", "34.21");
this.prices.put("ORCL", "31.22");
this.prices.put("RHT", "48.30");
this.prices.put("VMW", "66.98");
}
public Set<Quote> generateQuotes() {
Set<Quote> quotes = new HashSet<>();
for (String ticker : this.prices.keySet()) {
BigDecimal price = getPrice(ticker);
quotes.add(new Quote(ticker, price));
}
return quotes;
}
private BigDecimal getPrice(String ticker) {
BigDecimal seedPrice = new BigDecimal(this.prices.get(ticker), mathContext);
double range = seedPrice.multiply(new BigDecimal(0.02)).doubleValue();
BigDecimal priceChange = new BigDecimal(String.valueOf(this.random.nextDouble() * range), mathContext);
return seedPrice.add(priceChange);
}
}
}
Any idea?