Connecting to SQL server database with JavaFX [duplicate] - sql-server

Can anyone give me one example of a class that connects JavaFX with MySQL, dont want Main class, have one, just want a example of a class that connects any application to a MySQL database and gets a row from that database into a table, searched the whole internet and i didn't find anything straight to the point i do not want anything fancy just something to get the job done please.
Something clean and simple.

At a minimum, you need three classes: one to represent your data, one for your UI, and one to manage the database connection. In a real app you'd need more than this, of course. This example follows the same basic example as the TableView tutorial
Suppose your database has a person table with three columns, first_name, last_name, email_address.
Then you would write a Person class:
import javafx.beans.property.StringProperty ;
import javafx.beans.property.SimpleStringProperty ;
public class Person {
private final StringProperty firstName = new SimpleStringProperty(this, "firstName");
public StringProperty firstNameProperty() {
return firstName ;
}
public final String getFirstName() {
return firstNameProperty().get();
}
public final void setFirstName(String firstName) {
firstNameProperty().set(firstName);
}
private final StringProperty lastName = new SimpleStringProperty(this, "lastName");
public StringProperty lastNameProperty() {
return lastName ;
}
public final String getLastName() {
return lastNameProperty().get();
}
public final void setLastName(String lastName) {
lastNameProperty().set(lastName);
}
private final StringProperty email = new SimpleStringProperty(this, "email");
public StringProperty emailProperty() {
return email ;
}
public final String getEmail() {
return emailProperty().get();
}
public final void setEmail(String email) {
emailProperty().set(email);
}
public Person() {}
public Person(String firstName, String lastName, String email) {
setFirstName(firstName);
setLastName(lastName);
setEmail(email);
}
}
A class to access the data from the database:
import java.sql.Connection ;
import java.sql.DriverManager ;
import java.sql.SQLException ;
import java.sql.Statement ;
import java.sql.ResultSet ;
import java.util.List ;
import java.util.ArrayList ;
public class PersonDataAccessor {
// in real life, use a connection pool....
private Connection connection ;
public PersonDataAccessor(String driverClassName, String dbURL, String user, String password) throws SQLException, ClassNotFoundException {
Class.forName(driverClassName);
connection = DriverManager.getConnection(dbURL, user, password);
}
public void shutdown() throws SQLException {
if (connection != null) {
connection.close();
}
}
public List<Person> getPersonList() throws SQLException {
try (
Statement stmnt = connection.createStatement();
ResultSet rs = stmnt.executeQuery("select * from person");
){
List<Person> personList = new ArrayList<>();
while (rs.next()) {
String firstName = rs.getString("first_name");
String lastName = rs.getString("last_name");
String email = rs.getString("email_address");
Person person = new Person(firstName, lastName, email);
personList.add(person);
}
return personList ;
}
}
// other methods, eg. addPerson(...) etc
}
And then a UI class:
import javafx.application.Application ;
import javafx.scene.control.TableView ;
import javafx.scene.control.TableColumn ;
import javafx.scene.control.cell.PropertyValueFactory ;
import javafx.scene.layout.BorderPane ;
import javafx.scene.Scene ;
import javafx.stage.Stage ;
public class PersonTableApp extends Application {
private PersonDataAccessor dataAccessor ;
#Override
public void start(Stage primaryStage) throws Exception {
dataAccessor = new PersonDataAccessor(...); // provide driverName, dbURL, user, password...
TableView<Person> personTable = new TableView<>();
TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName"));
TableColumn<Person, String> lastNameCol = new TableColumn<>("Last Name");
lastNameCol.setCellValueFactory(new PropertyValueFactory<>("lastName"));
TableColumn<Person, String> emailCol = new TableColumn<>("Email");
emailCol.setCellValueFactory(new PropertyValueFactory<>("email"));
personTable.getColumns().addAll(firstNameCol, lastNameCol, emailCol);
personTable.getItems().addAll(dataAccessor.getPersonList());
BorderPane root = new BorderPane();
root.setCenter(personTable);
Scene scene = new Scene(root, 600, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
#Override
public void stop() throws Exception {
if (dataAccessor != null) {
dataAccessor.shutdown();
}
}
public static void main(String[] args) {
launch(args);
}
}
(I just typed that in without testing, so there may be typos, missing imports, etc, but it should be enough to give you the idea.)

In addition to the answer of James_D:
I wanted to connect to a remote (MySQL) database, so I changed the constructor and connected by url-only:
public UserAccessor(String dbURL, String user, String password) throws SQLException, ClassNotFoundException {
connection = DriverManager.getConnection(dbURL, user, password);
}
Init via:
UserAccessor userAccessor = new UserAccessor(
"jdbc:mysql://xxx.xxx.xxx.xxx:YOUR_PORT", "YOUR_DB_USER", "YOUR_PASSWORD")
Please note:
You will also need to include the connector lib. I choosed mysql-connector-java-5.1.40-bin.jar which came with IntelliJ and was located under /Users/martin/Library/Preferences/IntelliJIdea2017.1/jdbc-drivers/MySQL Connector/J/5.1.40/mysql-connector-java-5.1.40-bin.jar
Kudos belong to James_D.

Related

Exception when trying to use DynamoDBMapper: no mapping for HASH key

I have a DynamoDB table with a primary key (id : integer) and secondary key (dateTo : String). I've made a Class that utilizes DynamoDBMapper:
#DynamoDBTable(tableName="MyItems"
public class MyItemsMapper {
private int id;
private String dateTo;
private String name;
#DynamoDBHashKey(attributeName="id")
public void setId(int id) { this.id = id; }
public int getId() { return id; }
#DynamoDBAttribute(attributeName="dateTo")
public void setDateTo(String dateTo) { this.dateTo = dateTo; }
public String getDateTo() { return dateTo; }
#DynamoDBAttribute(attributeName="name")
public void setName(String name { this.name = name; }
public String getName() { return name; }
public boolean saveItem(MyItemsMapper item) {
try {
DynamoDBMapper mapper = new DynamoDBMapper(client); //<-- This connects to the DB. This works fine.
item.setId(generateUniqueNumber()); //<-- This generates a unique integer. Also seems to work fine.
mapper.save(item);
logger.info("Successfully saved item. See info below.");
logger.info(item.toString());
return true;
} catch (Exception e) {
logger.error("Exception while trying to save item: " + e.getMessage());
e.printStackTrace();
return false;
}
}
}
I then have a manager class that uses the bean above, like so:
public class MyManager {
public boolean recordItem(
int id,
String dateTo,
String name,
) {
MyItemsMapper myItemsMapper = new MyItemsMapper();
myItemsMapper.setId(id);
myItemsMapper.setDateTo(dateTo);
myItemsMapper.setName(name);
myItemsMapper.saveItem(myItemsMapper);
}
}
I am running the manager class in a JUnit test:
public class MyManagerTest {
#Test
public void saveNewItemTest() {
MyManager myManager = new MyManager();
myManager.recordItem(1234567, "2018-01-01", "Anthony");
}
}
When I use the saveItem method above via my manager by running my JUnit test, I get the following error:
com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException: MyItemsMapper; no mapping for HASH key
Not really sure what it's pertaining to, as I definitely have a primary key for my table and my secondary key always has a value as well.
How do I get this to work?
More Info:
It's worth noting that I can record data into my DynamoDB table via the Item object. If I do the below, my data gets recorded into the database:
DynamoDB dynamoDB = new DynamoDBClient().connectToDynamoDB(); //<--
Connection. Works fine.
Table table = dynamoDB.getTable("MyItems");
item.withPrimaryKey("id", 1234567);
item.withString("dateTo", "2018-01-01");
item.withString("name", "Anthony");
PutItemOutcome outcome = table.putItem(item);
However, I'm trying to use DynamoDBMapper because I'm reading that it is a more organized, better way to access data.
Im not sure if this is causing the problem, but you are creating the myItemsMapper object, then passing a reference to this object to itself.
I would suggest removing your saveItem method. The MyItemsMapper class should be a plain old java object. Then make MyManager like this
public class MyManager {
public boolean recordItem(
int id,
String dateTo,
String name,
) {
MyItemsMapper myItemsMapper = new MyItemsMapper();
myItemsMapper.setId(id);
myItemsMapper.setDateTo(dateTo);
myItemsMapper.setName(name);
DynamoDBMapper mapper = new DynamoDBMapper(client);
mapper.save(myItemsMapper);
}
}
If you particularly want to keep the saveItem method make it like this
public boolean saveItem() {
try {
DynamoDBMapper mapper = new DynamoDBMapper(client);
mapper.save(this);
logger.info("Successfully saved item. See info below.");
logger.info(this.toString());
return true;
} catch (Exception e) {
logger.error("Exception while trying to save item: " + e.getMessage());
e.printStackTrace();
return false;
}
}
And then in MyManager do
MyItemsMapper myItemsMapper = new MyItemsMapper();
myItemsMapper.setId(id);
myItemsMapper.setDateTo(dateTo);
myItemsMapper.setName(name);
myItemsMapper.saveItem();

Tableview update database on edit

So the thing that i want to happen, is making the tableview update the data in the database after editing it. I wanted to use the SetOnEditCommit method here. The cell editing does work, but it never gets updated, with no error either. In the first place im a bit clueless if this method is actually efficient (probably not), since its hard to find some sources for this specific thing. And the sources that i found weren't really helpful. So it would be nice if someone had an idea as to why it doesn't update, or maybe provide an alternate option here.
The mentioned part:
columnType.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<UserDetails, String>>() {
#Override
public void handle(TableColumn.CellEditEvent<UserDetails, String> event) {
updataData();
}
});
tableview.setItems(null);
tableview.setItems(data);
}
public void updataData() {
Connection connection = null;
try {
connection = DriverManager.getConnection("jdbc:mysql://37.128.148.113:3306/FYS", "FYS", "Kcj8g87~");
Statement con = connection.createStatement();
//connection
TablePosition pos = tableview.getSelectionModel().getSelectedCells().get(0);
int row = pos.getRow();
TableColumn col = pos.getTableColumn();
String data1 = (String) col.getCellObservableValue(row).getValue();
//cell
UserDetails row1 = tableview.getSelectionModel().getSelectedItem();
c1 = row1.getId();
//row
//tableview variables
con.execute("UPDATE gevonden_bagage SET type = 'data1' WHERE koffer_id = 'c1' ");
//Query
} catch (SQLException ex) {
System.err.println("Error" + ex);
}
}
//get connection, get celldata, get id data from first row, update cell with selected id
full controller class:
package simple;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
/**
*
* #author admin
*/
public class FXMLUserController extends SimpleController implements Initializable {
#FXML
public TableView<UserDetails> tableview;
#FXML
public TableColumn<UserDetails, String> columnId;
#FXML
public TableColumn<UserDetails, String> columnType;
#FXML
public TableColumn<UserDetails, String> columnKleur;
#FXML
public TableColumn<UserDetails, String> columnLuchthaven;
#FXML
public TableColumn<UserDetails, String> columnKenmerken;
#FXML
public TableColumn<UserDetails, String> columnStatus;
#FXML
public TableColumn<UserDetails, String> columnDatum;
#FXML
private Button btnLoad;
//declare observable list for database data
private ObservableList<UserDetails> data;
private DbConnection dc;
String c1;
#FXML
//strings for getRow method
#Override
public void initialize(URL url, ResourceBundle rb) {
dc = new DbConnection();
loadDataFromDatabase();
}
#FXML
public void loadDataFromDatabase() {
try {
Connection conn = dc.Connect();
data = FXCollections.observableArrayList();
// Execute query and store result in a resultset
ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM gevonden_bagage");
while (rs.next()) {
//get strings
data.add(new UserDetails(rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getString(5),
rs.getString(6), rs.getString(7)));
}
} catch (SQLException ex) {
System.err.println("Error" + ex);
}
//Set cell values to tableview.
tableview.setEditable(true);
tableview.getSelectionModel().setCellSelectionEnabled(true);
columnType.setCellFactory(TextFieldTableCell.forTableColumn());
columnKleur.setCellFactory(TextFieldTableCell.forTableColumn());
columnLuchthaven.setCellFactory(TextFieldTableCell.forTableColumn());
columnKenmerken.setCellFactory(TextFieldTableCell.forTableColumn());
columnStatus.setCellFactory(TextFieldTableCell.forTableColumn());
columnDatum.setCellFactory(TextFieldTableCell.forTableColumn());
//makes columns editable
columnId.setCellValueFactory(new PropertyValueFactory<>("id"));
columnType.setCellValueFactory(new PropertyValueFactory<>("type"));
columnKleur.setCellValueFactory(new PropertyValueFactory<>("kleur"));
columnLuchthaven.setCellValueFactory(new PropertyValueFactory<>("luchthaven"));
columnKenmerken.setCellValueFactory(new PropertyValueFactory<>("kenmerken"));
columnStatus.setCellValueFactory(new PropertyValueFactory<>("status"));
columnDatum.setCellValueFactory(new PropertyValueFactory<>("datum"));
columnType.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<UserDetails, String>>() {
#Override
public void handle(TableColumn.CellEditEvent<UserDetails, String> event) {
updataData();
}
});
tableview.setItems(null);
tableview.setItems(data);
}
public void updataData() {
Connection connection = null;
try {
connection = DriverManager.getConnection("jdbc:mysql://37.128.148.113:3306/FYS", "FYS", "Kcj8g87~");
Statement con = connection.createStatement();
//connection
TablePosition pos = tableview.getSelectionModel().getSelectedCells().get(0);
int row = pos.getRow();
TableColumn col = pos.getTableColumn();
String data1 = (String) col.getCellObservableValue(row).getValue();
//cell
UserDetails row1 = tableview.getSelectionModel().getSelectedItem();
c1 = row1.getId();
//row
//tableview variables
con.execute("UPDATE gevonden_bagage SET type = 'data1' WHERE koffer_id = 'c1' ");
//Query
} catch (SQLException ex) {
System.err.println("Error" + ex);
}
}
//get connection, get celldata, get id data from first row, update cell with selected id
#FXML
public void getRow() {
TablePosition pos = tableview.getSelectionModel().getSelectedCells().get(0);
int row = pos.getRow();
TableColumn col = pos.getTableColumn();
// this gives the value in the selected cell:
String data1 = (String) col.getCellObservableValue(row).getValue();
System.out.println(data1);
//CURRENTLY UNUSED METHOD
}
}
Model class:
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
/**
*
* #author admin
*/
public class UserDetails {
private final StringProperty id;
private final StringProperty type;
private final StringProperty kleur;
private final StringProperty luchthaven;
private final StringProperty kenmerken;
private final StringProperty status;
private final StringProperty datum;
//Default constructor
public UserDetails(String id, String type, String kleur, String luchthaven, String kenmerken, String status, String datum) {
this.id = new SimpleStringProperty(id);
this.type = new SimpleStringProperty(type);
this.kleur = new SimpleStringProperty(kleur);
this.luchthaven = new SimpleStringProperty(luchthaven);
this.kenmerken = new SimpleStringProperty(kenmerken);
this.status = new SimpleStringProperty(status);
this.datum = new SimpleStringProperty(datum);
}
//getters
public String getId() {
return id.get();
}
public String getType() {
return type.get();
}
public String getKleur() {
return kleur.get();
}
public String getLuchthaven() {
return luchthaven.get();
}
public String getKenmerken() {
return kenmerken.get();
}
public String getStatus() {
return status.get();
}
public String getDatum() {
return datum.get();
}
//setters
public void setId(String value) {
id.set(value);
}
public void setType(String value) {
type.set(value);
}
public void setKleur(String value) {
kleur.set(value);
}
public void setLuchthaven(String value) {
luchthaven.set(value);
}
public void setKenmerken(String value) {
kenmerken.set(value);
}
public void setStatus(String value) {
status.set(value);
}
public void setDatum(String value) {
datum.set(value);
}
//property values
public StringProperty idProperty() {
return id;
}
public StringProperty typeProperty() {
return type;
}
public StringProperty kleurProperty() {
return kleur;
}
public StringProperty luchthavenProperty() {
return luchthaven;
}
public StringProperty kenmerkenProperty() {
return kenmerken;
}
public StringProperty statusProperty() {
return status;
}
public StringProperty datumProperty() {
return datum;
}
}
From the TableView documentation:
By default the TableColumn edit commit handler is non-null, with a
default handler that attempts to overwrite the property value for the
item in the currently-being-edited row. It is able to do this as the
Cell.commitEdit(Object) method is passed in the new value, and this is
passed along to the edit commit handler via the CellEditEvent that is
fired. It is simply a matter of calling
TableColumn.CellEditEvent.getNewValue() to retrieve this value.
It is very important to note that if you call
TableColumn.setOnEditCommit(javafx.event.EventHandler) with your own
EventHandler, then you will be removing the default handler. Unless
you then handle the writeback to the property (or the relevant data
source), nothing will happen.
So the problem is that by setting the onEditCommit on columnType, you remove the default handler that actually updates typeProperty in the UserDetails instance. Consequently
String data1 = (String) col.getCellObservableValue(row).getValue();
gives the old value, and your update to the database won't change anything.
Additionally, you have errors in the way you create the SQL statement. You are making the id in the WHERE clause the literal value 'c1' (instead of the value contained in the variable c1, and similarly setting the value of type to the literal value 'data1', instead of the value in the variable data1.
Here is a fix, along with some simplification of the code and some better practices for avoiding SQL injection attacks:
columnType.setOnEditCommit(event -> {
UserDetails user = event.getRowValue();
user.setType(event.getNewValue());
updateData("type", event.getNewValue(), user.getId());
});
and then
private void updateData(String column, String newValue, String id) {
// btw it is way better to keep the connection open while the app is running,
// and just close it when the app shuts down....
// the following "try with resources" at least makes sure things are closed:
try (
Connection connection = DriverManager.getConnection("jdbc:mysql://37.128.148.113:3306/FYS", "FYS", "Kcj8g87~");
PreparedStatement stmt = connection.prepareStatement("UPDATE gevonden_bagage SET "+column+" = ? WHERE koffer_id = ? ");
) {
stmt.setString(1, newValue);
stmt.setString(2, id);
stmt.execute();
} catch (SQLException ex) {
System.err.println("Error");
// if anything goes wrong, you will need the stack trace:
ex.printStackTrace(System.err);
}
}

App Engine endpoint to accept POST data in request body

I have created a Google Endpoint in my App Engine Server as follows:
package com.xxxxx.gcmbackend;
import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.ApiNamespace;
import com.google.api.server.spi.response.CollectionResponse;
import java.util.List;
import java.util.logging.Logger;
import javax.inject.Named;
import static com.xxxxxx.gcmbackend.OfyService.ofy;
#Api(
name = "register",
version = "v1",
namespace = #ApiNamespace(
ownerDomain = "gcmbackend.xxxxx.com",
ownerName = "gcmbackend.xxxxx.com",
packagePath=""
)
)
public class UserRegistrationEndpoint {
private static final Logger log = Logger.getLogger(RegistrationEndpoint.class.getName());
#ApiMethod(name = "register")
public void registerDevice(#Named("regId") String regId, #Named("username") String username, #Named("phone") String phone) {
if(findRecord(regId) != null) {
log.info("Device " + regId + " already registered, skipping register");
return;
}
RegistrationRecord record = new RegistrationRecord();
record.setRegId(regId);
record.setUsername(username);
record.setPhone(phone);
ofy().save().entity(record).now();
}
private RegistrationRecord findRecord(String regId) {
return ofy().load().type(RegistrationRecord.class).filter("regId", regId).first().now();
}
}
This works perfectly in creating new User records. The API is of the following format:
http://example.appspot.com/_ah/api/register/v1/registerDevice/<regId>/<username>/<phone>
However, I want the url to look like this:
http://example.appspot.com/_ah/api/register/v1/registerDevice/
and then send POST data as follows:
{
regId: "some_value",
username: "some_value",
phone: "some_value"
}
What do I need to change in my Endpoint in order to achieve this format?
You need to create a java bean with regId, username and phone attributes e.g. RegistrationInput.
public class RegistrationInput {
private String regId;
private String username;
private String phone;
public String getRegId() {
return regId;
}
public void setRegId(String regId) {
this.regId = regId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
Then add the above java bean RegistrationInput, as a parameter to the ApiMethod
#ApiMethod(name = "register")
public void registerDevice(RegistrationInput input) {
.....
}

Uncaught exception from servlet java.io.IOException at app engine. 500 Server Error after running app second time

I have just started with App Engine and I have tried to make a very simple app which adds Person objects with distinctive names to the datastore. This the object:
#PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Person {
#PrimaryKey
#Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;
#Persistent
#Unique
private String name;
public Person(String nameIn){
this.name = nameIn;
}
public Long getId(){
return this.id;
}
public void setId(Long idIn){
this.id = idIn;
}
}
This servlet is responsible for persisting objects on datastore. But prior to that, the method doesUserExist(String) checks whether object with the same 'name' field exists:
#SuppressWarnings("serial")
public class PersonDatastoreServlet extends HttpServlet {
private static final String PARAM_NAME = "name";
private PersistenceManager pmf = PMF.get().getPersistenceManager();
public void doGet(HttpServletRequest req, HttpServletResponse response)
throws IOException {
String name = req.getParameter(PARAM_NAME);
PrintWriter printWriter = response.getWriter();
try{
if(!doesUserExist(name)) {
Person p = new Person(name);
pmf.makePersistent(p);
response.setContentType("text/html");
printWriter.println("<h1>"+p.getId()+"</h1>");
}
else {
response.setContentType("text/html");
printWriter.println("<p>User already exists</p>");
}
}
catch(Exception e) {
throw new IOException();
}
finally{
pmf.close();
}
}
private boolean doesUserExist(String nameIn) {
Query q = pmf.newQuery(Person.class);
q.setFilter("name == lastNameParam");
q.declareParameters("String lastNameParam");
String name = nameIn;
try{
List<Person> list = (List<Person>) q.execute(name);
if (list.isEmpty()){
return false;
}
else return true;
}
finally{
q.closeAll();
}
}
}
The take seems very straightforward, but it just not working. I have a form which processing the request. When I run my app for the first time it does successfully create and persist an object, however whenever i want to add another object with a different name, I am getting the Error
Error: Server Error
The server encountered an error and could not complete your request.
If the problem persists, please report your problem and mention this error message and the query that caused it.
It indicates that the query causes the problem but I have idea what is wrong with my query. Can anybody help please?

Save gwt entities to google application engine datastore with jdo, using rpc

Hello iam new to GWT framework. I want to persist my domain objects/entities to google application engine datastore using rpc. A simple implementation to test if i can make multiple rpc calls ( greetServer() , saveStudent() )
Student
import javax.jdo.annotations.Extension;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import com.google.gwt.user.client.rpc.IsSerializable;
#PersistenceCapable
public class Student implements IsSerializable {
private static final long serialVersionUID = 1L;
#PrimaryKey
#Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
#Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
private int studentId;
#Persistent private String firstName;
#Persistent private String lastName;
public Student(){}
public Student(String firstName, String lastName){
this.firstName = firstName;
this.lastName = lastName;
}
public void setStudentId(int studentId) {
this.studentId = studentId;
}
public int getStudentId() {
return studentId;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getLastName() {
return lastName;
}
}
GreetingService (default code generated by Eclipse IDE)
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
#RemoteServiceRelativePath("greet")
public interface GreetingService extends RemoteService {
String greetServer(String name) throws IllegalArgumentException;
**String saveStudent(Student s) throws IllegalArgumentException;**
}
GreetingServiceAsync
import com.google.gwt.user.client.rpc.AsyncCallback;
public interface GreetingServiceAsync {
void greetServer(String input, AsyncCallback<String> callback)
throws IllegalArgumentException;
**void saveStudent(Student s, AsyncCallback<String> callback)
throws IllegalArgumentException;**
}
GreetingServiceImpl
import javax.jdo.PersistenceManager;
import com.d.client.GreetingService;
import com.d.client.Student;
import com.d.shared.FieldVerifier;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
#SuppressWarnings("serial")
public class GreetingServiceImpl extends RemoteServiceServlet implements
GreetingService {
public String greetServer(String input) throws IllegalArgumentException
...
String serverInfo = getServletContext().getServerInfo();
String userAgent = getThreadLocalRequest().getHeader("User-Agent");
...
}
#Override
public String saveStudent(Student s) throws IllegalArgumentException {
PersistenceManager pm = PMF.get().getPersistenceManager();
pm.makePersistent(s);
return "student save - ok";
}
}
PMF
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManagerFactory;
public final class PMF {
private static final PersistenceManagerFactory pmfInstance = JDOHelper
.getPersistenceManagerFactory("transactions-optional");
private PMF() {
}
public static PersistenceManagerFactory get() {
return pmfInstance;
}
}
EntryPoint
...
private final GreetingServiceAsync greetingService = GWT
.create(GreetingService.class);
greetingService.greetServer("greet",
new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
// Show the RPC error message to the user
}
public void onSuccess(String result) {
//Show success message
}
});
greetingService.saveStudent(new Student("kostas","trichas"),
new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
// Show the RPC error message to the user
}
public void onSuccess(String result) {
//Show success message
}
});
...
Is the above implementation correct? I deployed this sample application to gae and it did not persisted the object student (you can browse the entities at gae datastore viewer)
check it please:
http://gwtgaedatastore.appspot.com
Change your int studentID to Long id to get it working
This works with your original code (ie., Long id):
#Extension (vendorName="jpox", key="key-auto-increment" ,value="true")
Or, change id to String and your orig code works.
I could not get Long PK to work with datanucleus using gae.pk-id.

Resources