I want to build in a select with the possibility of marking more elements. So multiple="true". I use mysql and the Dao Technology of spring. I get the values for the select from database successfully. But now I have a problem when inserting the selected values to my database.
The important tables for that are:
The table demo.instrumente is filled with data like guitar, piano, etc. and an id. These values (i.e. guitar, piano) are displayed in the multiple select.
A user is able to select maybe 2 or 3 instruments. So I need to add the following instruments to the students. I do this with the table schueler_instrumente. Every student and instrument has an id. So i need to create data like this:
student_id 1 and instrument_id 2
student_id 1 and instrument_id 5
Here is my code for the instrument model class:
public class Instrumente {
private Integer instrumentid;
private String instrumentname;
//...getters and setters
}
This code is part of my controller:
#RequestMapping(method = RequestMethod.GET)
public String showUserForm(ModelMap model) {
model.put("instrumentListe", schuelerManager.getinstrumente());
return "usercenter";
}
And here's the relevant part of my schuelerManager
public Map<String, String> getinstrumente() {
Map<String,String> result = new LinkedHashMap<String,String>();
for (Instrumente instrument : instrumentDao.getInstrumente()) {
result.put(instrument.getInstrumentid().toString(),
instrument.getInstrumentname());
}
return result;
}
And here's how I get the data from my database:
public List<Instrumente> getInstrumente() {
return getJdbcTemplate().query("SELECT * FROM instrumente",
new RowMapper<Instrumente>() {
public Instrumente mapRow(ResultSet rs,
int rowNum)
throws SQLException {
Instrumente instrument = new Instrumente();
instrument.setInstrumentid
(rs.getInt("Instrument_ID"));
instrument.setInstrumentname
(rs.getString("Instrumentenbezeichnung"));
return instrument;
}
});
}
I do now know what I need to do in order to get the selected values from the select list. What do I have to write to the path="?" in the jsp.
I think that I can get a list of values back but how can I insert this list to my table schueler_instrument. Did I need to make a while or for repeat and make an insert everytime?
I can't find any nice example on the Internet. I hope someone can show me how to do this maybe with some code snippets.
In your controller's showUserForm() you are adding correctly your date to the ModelMap (or you could use its Java-5 counterpart Model). Now you'll need to use Spring's form tags in your view to represent the options in a dropdown/list way and receive onSubmit back in your controller the results that you will further persist in your db.
Have a look for a full example here.
Something that is not showcased in this example and I suggest you take a look is the #ModelAttribute annotation which is a nice way to communicate objects and values between your controller and your jsp view. For an example have a look in this tutorial.
Related
I have a problem with one functionality in my spring app. I have 2 tables in the same database, both contains the same type of data (id,title,description and date). And I can get the data from one table but don't know how to insert into 2nd table.
In my #Service layer i can get the data from table A. But dont know how to convert into another class object (both classes contain the samne data)
Injected JpaRepositories
private TasksRepository theTasksRepository;
private TasksRepositoryArchive theTasksRepositoryArchive;
And there's code to get the object from table A (TasksRepository - JpaRepository)
public Tasks findById(int theId) {
//Check if value is null or not null
Optional<Tasks> result = theTasksRepository.findById(theId);
Tasks theTask = null;
if (result.isPresent())
{
//if value is not null
theTask = result.get();
}
else
{
//if value is null
throw new RuntimeException("Task with given ID couldn't be found " +theId );
}
return theTask;
}
1) Define 2 entities, one for each table. To copy data, create an instance of the 2nd type and, copy properties, save. To copy properties there are many ways: you cann call each getter and setter manually, you can use some libraries like Dozer or MapStruct. Don't forget to set ID to null.
2) If you want to have an archive of changes, use libraries that help to implement it. For instance, consider using Enverse.
I am new to ADF and it seems I am missing something. I am using the Oracle HR database. I am using Business Components as the Model. I have ViewObjects for Country, Location and Department. As well as ViewLinks by FK between Country-Location and Location-Department. I exposed a DataControl Country-> Location -> Deperatments.
So now I can build a JSF with three areas in which each is shown. If I click on a country I get the locations. If I then click on location I get the departments. That works.
But I want to show only Country and Departments. So I implemented a managed bean to make use of the iterators and populate the department table throught that bean, by binding it to the value attribute of the table. But I only have Row objects to return and due to use of BC no Class definitions which I could map my rows back to objects.
So how can I just show all Departments in a Country? What is the ADF way to do this?
My managed bean:
public class CountryDepartmensBean {
public CountryDepartmensBean() {
super();
}
private ArrayList<Row> populate;
public ArrayList<Row> getPopulate() {
DCBindingContainer bindings = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
DCIteratorBinding countriesView1Iterator = bindings.findIteratorBinding("CountriesView1Iterator");
DCIteratorBinding locationsView2Iterator = bindings.findIteratorBinding("LocationsView2Iterator");
DCIteratorBinding departmentsView3Iterator = bindings.findIteratorBinding("DepartmentsView3Iterator");
Row[] locations = locationsView2Iterator.getAllRowsInRange();
ArrayList<Row> employees = new ArrayList<Row>();
for(int i = 0; i < locations.length; i++){
locationsView2Iterator.setCurrentRowIndexInRange(i);
departments.addAll(Arrays.asList(departmentsView3Iterator.getAllRowsInRange()));
}
return departments;
}
public void setPopulate(Row[] rows){
}
}
the getPopulate Method is called and returns the rows that I want, but returing rows seems to be the wrong way to go?
Using managed bean for this case is a wrong way itself.
All you need is to create viewObject that will match your expectation.
Create a viewObject joining Location + Department tables. Make it child to Country viewObject through viewLink. Now you can drag&drop master-detail tables on the page.
I have a legacy database and I'm developing a Spring MVC application with JPA/Hibernate. My problem comes with the generation of the composite primary keys. An example of primary key is composed like this:
Serial, Year, OrderID, LineId
LineId will be generated based on the max(LineId) for each tuple of Serial, Year and LineId.
I've thought about the following ways:
PrePersist Listener: It means the listener would have to access repositories and even maybe have references to other entities in order to get the next id. EDIT: Hibernate Docs say: A callback method must not invoke EntityManager or Query methods!. https://docs.jboss.org/hibernate/orm/4.0/hem/en-US/html/listeners.html#d0e3013
Custom Generator: I haven't found a single example that shows how to access the entity's instance to retrieve the properties I need to do a proper select.
Service Layer: Would be just too verbose.
Overriding the Spring's Data's JPA Repository save() method implmentation: In this case, Here we could access the entity's instance properties.
What is the correct way to achieve this purpose? Thanks
What I have often done to support this is to use a domain-driven design technique where I control this at the time I associate an OrderLine to the Order.
public class Order {
private List<OrderLine> lines;
// don't allow the external world to modify the lines collection.
// forces them to use domain driven API exposed below.
public List<OrderLine> getLines() {
return Collections.unmodifiableList( lines );
}
// avoid allowing external sources to set the lines collection
// Hibernate can set this despite the method being private.
private void setLines(List<OrderLine> lines) {
this.lines = lines;
}
public OrderLine addLine(String serial, Integer year) {
final OrderLine line = new OrderLine( this, serial, year );
lines.add( line );
return line;
}
public void removeLine(Integer lineId) {
lines.removeIf( l -> l.getId().getLineId().equals( lineId ) );
}
}
public OrderLine {
public OrderLine() {
}
OrderLine(Order order, String serial, Integer year) {
this.id = new OrderLineId( order.getLines().size() + 1, serial, year, order.getId() );
}
}
The only code which ever calls the special OrderLine constructor is called from Order and you make sure that you always delegate the addition and removal of OrderLine entities through the aggregate root, Order.
This also implies you only ever need to expose an Order repository and you manipulate the lines associated with an Order only through an Order and never directly.
I have two classes. The OrderSlip class has a one-to-many relationship with orderedItemDescription.
class OrderSlip {
String employeeID
int serving
int tableNumber
static hasMany = [orderedItemDescription: OrderedItemDescription]
}
class OrderedItemDescription {
MenuItem menuItem
MenuItemProgressStatus progress//progress
String descriptionOfOrder
int quantity = 1
static belongsTo = OrderSlip
}
Now my problem is how do i iterate orderedItemDescription so that when i update my orderSlip i can add many orderedItemDescriptions along with its properties.
def updateOrderSlip(Long id) {
User currentUser = springSecurityService.currentUser
def orderSlipInstance = Table.get(id)
//other codes for orderedItemDescription here
orderSlipInstance.employeeID = currentUser.username
orderSlipInstance.serving= Integer.parseInt(params.serving)
orderSlipInstance.tableNumber= params.tableNumber
render(action:'server')
}
Im doing something like this in my gsp. im only adding data to the DOM with the add buttons. Then for the send order im hoping i can update it like the problem since im also adding many g:hiddenField for each orderedItemDescription in my summary
You should be persisting each new instance OrderedItemDescription somehow.
You can store it immediately in the DB upon click on add-button with the status flag set to incomplete. When you save the whole order, you must change the incomplete to complete.
Another option would be to keep the items in the http session. Upon send order you iterate through the in-session items and persist them all along with the order instance.
Both ways have advantages and drawbacks, but they both are useful.
I am working on an android app that loads in a list of students to display in a list based activity. There are two components to the app. There is a server which responds via xml with the list of current active students and a database on the app end which stores theses students with some details (name,age etc). I would like a way to sync these two data sources. When the app starts, I would like to check against the xml to see if students on the server were added/deleted and update the db accordingly.
I would be parsing the xml list into a student object at login. Is there any way to store/retrieve an entire object into an android supported db so I can do a direct comparison to see what to update/delete? It would end up being something like
if (serverStudent[0].name == dbStudent[0].name)
//overwrite dbStudent object with serverStudent fields
What is the most efficient/lightweight way to achieve object persistance and then comparison in Android?
Here's a method I have used in the past:
Anytime an object in the database is changed, use a timestamp column to store that time. When the app connects on startup, simply check each timestamp in the app db against the timestamp in the server db for each object. If the timestamps match, do nothing. If the timestamps don't match, retrieve the updated record from the server. Make sure you're using a detail enough timestamp (usually down to milli- or micro- seconds).
The nice thing about timestamps is that if you don't want the server data to override the app data, you could look at which is newer and keep that object if they've both been edited. Just adding some additional thoughts!
You can do something like this -
public class StudentRecord {
Vector<StudentData> studentDatas;
public StudentRecord()
{
studentDatas = new Vector<StudentData>();
}
public Vector<StudentData> getRecords() {
return studentDatas;
}
public void setRecords(Vector<StudentData> records) {
this.studentDatas = records;
}
public class StudentData
{
String name,Rollno;
public String getRollno() {
return Rollno;
}
public void setRollno(String rollno) {
Rollno = rollno;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
When you get the vector object studentDatas you can do something like this -
for(Object object : record.getRecords())
{
data = (StudentData)object;
data.getRollno();
data.getName();
}
Check out these libraries:
http://www.datadroidlib.com/
https://github.com/octo-online/robospice
I believe both offer solutions for your situation.
Or you can roll your own solution... Basically you will want to create a service or asynctask to do the syncing, in your student object you can create a constructor that you can pass an id to and have it pull the appropriate record from your local db then make a comparison method that will update if newer information is available.
I'm not sure i understood your question correctly.But as far as i understand i would do something like this.
In server side send send Json array which holds json student objects.
In android side create similer Student class and override equals
method as you want.
Then for each student check with equals method whether they are
equals or not and take action accordingly.
If you want to make faster search in students object array then apply
hash map instead of arrays.