I have two entities: Student and Info and they linked by a #ManytoOne relationship. The entity Info is used to handle file upload and store upload file in database. I m able to save file path in database.but Not With Student_id. i want to save file with student id. and show the uploaded file with in table format.Any example suggestions are appreciated. I m new to web development.thanks Two Model entities linked by a #ManytoOne relationship. Model Info is as follows.
package models;
#Entity
public class Info extends Model {
public static Info findById(Long id) {
return find.byId(id);
}
#Id
public Long id;
public String picture;
#ManyToOne(cascade = CascadeType.PERSIST)
private Student student;
public static Model.Finder<Long, Info> find =
new Model.Finder<Long, Info>(Long.class, Info.class);
public Info(){
// Left empty
}
public Info(Student student ,Long id){
this.customer=customer;
this.id=id;
}
public String toString() {
return String.format("%s" ,id);
}
public void setPicture(String picture) {
this.picture = picture;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public String getPicture() {
return picture;
}
}
another student model
package models;
#Entity
public class Info extends Model{
private static List<Info> products;
#Id
public Long id;
public String name;
#OneToMany(mappedBy="student")
private List<Info> info;
public static Finder<Long, Student> find = new Finder<Long, Student>(Long.class, Student.class);
public Student() {
}
public Student(String btn){
this.btn = btn;
this.info = new ArrayList<Info>();
}
public String toString() {
return String.format("%s - %s" ,id, business_address);
}
public static Student findById(Long id) {
return find.where().eq("id", id).findUnique();
}
public List<Info> getInfo() {
return info;
}
public void setInfo(List<Info> info) {
this.info = info;
}
}
and InfoCon Controller is as follows
package controllers;
import java.io.File;
public class InfoCon extends Controller {
private static final Form<Info> infoForm = Form.form(Info.class);
public static Result save() {
Form<Info> boundForm = infoForm.bindFromRequest();
Info info = boundForm.get();
Http.MultipartFormData body = request().body().asMultipartFormData();
Http.MultipartFormData.FilePart picture = body.getFile("picture");
if (picture != null) {
String fileName = picture.getFilename();
String contentType = picture.getContentType();
File file = picture.getFile();
File newFile = new File("C:\\Folder1\\store\\"+ "_" + fileName);
file.renameTo(newFile); //here you are moving file to new directory
info.setPicture(newFile.getPath());
if (info.id == null) {
info.save();
}
return ok("File uploaded");
} else {
flash("error", "Missing file");
return redirect(routes.Application.index());
}
}
public static Result info(Long id) {
final Student student = Student.findById(id);
Info wk = new Info();
Form<Info> filledForm = infoForm.fill(wk);
return ok(info.render(filledForm));
}
}
Related
I am currently building an android app, which displays a Route, which is constructed out of multiple waypoints. I already planned the database schema (chen-notation [possibly invalid "syntax"]):
I tried to recreate the n-m relation with android room, but I can't figure out how I can retrieve the index_of_route attribute of the junction table (route_waypoint).
I want the junction table attribute index_of_route, when I get the Data like so:
#Transaction
#Query("SELECT * FROM POIRoute")
List<RouteWithWaypoints> getRoutes();
inside the POIWaypoint class (maybe as extra attribute), or at least accessible from another class which maybe is implemented like so:
#Embedded
POIWaypoint waypoint;
int indexOfRoute;
Currently I don't get the indexOfRoute attribute from the junction table.
My already created classes:
RouteWithWaypoints:
public class RouteWithWaypoints {
#Embedded
private POIRoute poiRoute;
#Relation(parentColumn = "id",entityColumn = "id",associateBy = #Junction(value = RouteWaypoint.class, parentColumn = "routeId", entityColumn = "waypointId"))
private List<POIWaypoint> waypoints;
public POIRoute getPoiRoute() {
return poiRoute;
}
public void setPoiRoute(POIRoute poiRoute) {
this.poiRoute = poiRoute;
}
public List<POIWaypoint> getWaypoints() {
return waypoints;
}
public void setWaypoints(List<POIWaypoint> waypoints) {
this.waypoints = waypoints;
}
RouteWaypoint:
#Entity(primaryKeys = {"waypointId", "routeId"}, foreignKeys = {
#ForeignKey(entity = POIWaypoint.class, parentColumns = {"id"}, childColumns = {"waypointId"}),
#ForeignKey(entity = POIRoute.class, parentColumns = {"id"}, childColumns = {"routeId"})
})
public class RouteWaypoint {
private int waypointId;
private int routeId;
// I want this attribute inside the POIWaypoint class
#ColumnInfo(name = "index_of_route")
private int indexOfRoute;
public int getWaypointId() {
return waypointId;
}
public void setWaypointId(int waypointId) {
this.waypointId = waypointId;
}
public int getRouteId() {
return routeId;
}
public void setRouteId(int routeId) {
this.routeId = routeId;
}
}
POIRoute:
#Entity
public class POIRoute{
private String name;
private String description;
#PrimaryKey(autoGenerate = true)
private int id;
private boolean user_generated;
private int parentId;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public boolean isUser_generated() {
return user_generated;
}
public void setUser_generated(boolean user_generated) {
this.user_generated = user_generated;
}
public int getParentId() {
return parentId;
}
public void setParentId(int parentId) {
this.parentId = parentId;
}
}
POIWaypoint (please ignore the position attribute it isn't finished):
#Entity
public class POIWaypoint {
#PrimaryKey(autoGenerate = true)
private long id;
#ColumnInfo(name = "long_description")
private String longDescription;
private String title;
#ColumnInfo(name = "short_description")
private String shortDescription;
// use converter: https://developer.android.com/training/data-storage/room/referencing-data
#Ignore
private GeoPoint position;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public GeoPoint getPosition() {
return position;
}
public void setPosition(GeoPoint position) {
this.position = position;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getShortDescription() {
return shortDescription;
}
public void setShortDescription(String shortDescription) {
this.shortDescription = shortDescription;
}
public String getLongDescription() {
return longDescription;
}
public void setLongDescription(String longDescription) {
this.longDescription = longDescription;
}
I solved my problem by manage the relation by myself. I changed my RouteDao to an abstract class to insert my own method, which manages part of the junction table by itself:
RouteDao:
private RouteDatabase database;
public RouteDao(RouteDatabase database) {
this.database = database;
}
#Query("Select * from POIRoute")
public abstract List<POIRoute> getRoutes();
#Query("SELECT * FROM POIRoute WHERE id = :id")
public abstract POIRoute getRoute(int id);
#Insert
abstract void insertRouteWithWaypoints(RouteWithWaypoints routeWithWaypoints);
public List<RouteWithWaypoints> getRoutesWithWaypoints() {
List<POIRoute> routes = this.getRoutes();
List<RouteWithWaypoints> routesWithWaypoints = new LinkedList<>();
for (POIRoute r : routes) {
routesWithWaypoints.add(new RouteWithWaypoints(r, database.wayPointDao().getWaypointsFromRoute(r.getId())));
}
return routesWithWaypoints;
}
public RouteWithWaypoints getRouteWithWaypoints(int id) {
POIRoute route = this.getRoute(id);
RouteWithWaypoints routeWithWaypoints = null;
if (route != null) {
routeWithWaypoints = new RouteWithWaypoints(route, database.wayPointDao().getWaypointsFromRoute(route.getId()));
}
return routeWithWaypoints;
}
WayPointDao:
#Query("SELECT * FROM POIWaypoint")
POIWaypoint getWaypoints();
#Query("SELECT * FROM POIWaypoint WHERE id = :id")
POIWaypoint getWaypoint(long id);
#Query("SELECT pw.*, rw.index_of_route as 'index' FROM POIWaypoint as pw Join RouteWaypoint as rw on (rw.waypointId = pw.id) where rw.routeId = :id order by 'index' ASC")
List<POIRouteStep> getWaypointsFromRoute(int id);
I am using JSON-B for output object to json and there is a circular reference in the object (please do not ask me to remove the circular reference), sample code as follows
The Person class contains a list of Property
and the Property class reference back the person which form a circular reference.
In the first print the json can be output, however in the second print statement, stack overflow error due to touch the circular reference of the object, I do not want to use #JsonbTransient to ignore any of them, how can I solve this?
I am expecting the json output as
{"id":1,"name":"Jhon","propertyList":[{"person":1, "propertyName":"Palace"},{"person":1, "propertyName":"Apartment"}]}
Sample Code:
import java.util.ArrayList;
import java.util.List;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
public class JsonTest {
public static void main(String[] args) throws InterruptedException {
Person person = new Person(1, "Jhon");
Jsonb jsonb = JsonbBuilder.create();
//no error as no property is added
System.out.println("jsonPerson without property: " + jsonb.toJson(person));
Property p1 = new Property();
p1.setPropertyName("Palace");
p1.setPerson(person);
Property p2 = new Property();
p2.setPropertyName("Apartment");
p2.setPerson(person);
person.getPropertyList().add(p1);
person.getPropertyList().add(p2);
/**
* stackoverflow here
*/
System.out.println("jsonPerson with property: " + jsonb.toJson(person));
}
public static class Property {
private Person person;
private String propertyName;
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public String getPropertyName() {
return propertyName;
}
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
}
public static class Person {
private int id;
public Person() {
super();
}
public Person(int id, String name) {
super();
this.id = id;
this.name = name;
}
private String name;
private List<Property> propertyList = new ArrayList<>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Property> getPropertyList() {
return propertyList;
}
public void setPropertyList(List<Property> propertyList) {
this.propertyList = propertyList;
}
}
}
Finally I give up using JSON-B and instead use Jackson, use the annotation #JsonIdentityInfo here is my solution for information:
import java.util.ArrayList;
import java.util.List;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonTest {
private static Person person = null;
private static List<Property> propertyList = new ArrayList<>();
public static void main(String[] args) throws Exception {
person = new Person(1, "Jhon");
propertyList.add(new Property(1, person, "Palace"));
propertyList.add(new Property(2, person, "Apartment"));
person.setPropertyList(propertyList);
jacksonTest();
//jsonbTest();
}
private static void jacksonTest()
throws Exception
{
String result = new ObjectMapper().writeValueAsString(person);
System.out.println("result: " + result);
}
private static void jsonbTest()
throws Exception
{
Jsonb jsonb = JsonbBuilder.create();
/**
* stackoverflow here
*/
System.out.println("jsonPerson with property: " + jsonb.toJson(person));
}
public static class Property extends BaseEntity {
private Person person;
private String propertyName;
public Property(int id, Person person, String propertyName) {
super();
setId(id);
this.person = person;
this.propertyName = propertyName;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public String getPropertyName() {
return propertyName;
}
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
}
public static class Person extends BaseEntity {
public Person() {
super();
}
public Person(int id, String name) {
super();
setId(id);
this.name = name;
}
private String name;
private List<Property> propertyList = new ArrayList<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Property> getPropertyList() {
return propertyList;
}
public void setPropertyList(List<Property> propertyList) {
this.propertyList = propertyList;
}
}
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public static abstract class BaseEntity {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
}
Jackson output:
result: {"id":1,"name":"Jhon","propertyList":[{"id":1,"person":1,"propertyName":"Palace"},{"id":2,"person":1,"propertyName":"Apartment"}]}
I am trying to update a list of a company class I created in Play Framework.
It all works until i get to the company.update(), which doesn't save to the database as it should.
Here is my Company class:
package models;
import io.ebean.Finder;
import io.ebean.Model;
import javax.persistence.Entity;
import javax.persistence.Id;
#Entity
public class Company extends Model {
#Id
public Integer id;
public String code;
public String name;
public String adress;
public String fiscalCode;
public String bankAccount;
public static Finder<Integer, Company> find = new Finder<>(Company.class);
public String getFiscalCode() {
return fiscalCode;
}
public void setFiscalCode(String fiscalCode) {
this.fiscalCode = fiscalCode;
}
public String getBankAccount() {
return bankAccount;
}
public void setBankAccount(String bankAccount) {
this.bankAccount = bankAccount;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAdress() {
return adress;
}
public void setAdress(String adress) {
this.adress = adress;
}
}
And here are my update and edit methods:
public Result editCompany(Integer id){
Company company = Company.find.byId(id);
if(company == null)
{
return notFound("Company not found");
}
Form<Company> companyForm = formFactory.form(Company.class).fill(company);
return ok(editCompany.render(companyForm));
}
public Result updateCompany(){
Form<Company> companyForm = formFactory.form(Company.class).bindFromRequest();
if(companyForm.hasErrors())
{
flash("danger","Please Correct the Form Below");
return badRequest(editCompany.render(companyForm));
}
Company newcompany = companyForm.get();
Company company = Company.find.byId(newcompany.id);
if (company == null) {
flash("danger", "Book not found");
redirect(routes.CompanyController.indexCompanies());
}
company.code = newcompany.code;
company.name = newcompany.name;
company.adress = newcompany.adress;
company.fiscalCode = newcompany.fiscalCode;
company.bankAccount = newcompany.bankAccount;
company.update();
flash("success","Company Details Updated Successfully");
return redirect(routes.CompanyController.indexCompanies());
}
The new company entity has updated values, but they don't save in the database. I checked by printing to the console company.name.
I hope you can help me. Thank you!
I seem to have figured it out.
The problem goes away after using getters and setters and doing a recompile. Therefore,
company.code = newcompany.code;
company.name = newcompany.name;
company.adress = newcompany.adress;
company.fiscalCode = newcompany.fiscalCode;
company.bankAccount = newcompany.bankAccount;
becomes
company.setCode(newcompany.getCode());
company.setName(newcompany.getName());
company.setAdress(newcompany.getAdress());
company.setFiscalCode(newcompany.getFiscalCode());
company.setBankAccount(newcompany.getBankAccount());
I am new with using spring boot + jersey api + JPA.
I hava three entity that uses one to many bidirectional mapping. When i used spring boot + jersey api+ JPA I get error :
failed to lazily initialize a collection of role: com.kavinaam.GSTbilling.entity.Country.states, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.kavinaam.GSTbilling.entity.City["states"]->com.kavinaam.GSTbilling.entity.States["countyId"]->com.kavinaam.GSTbilling.entity.Country["states"])
I have added my entity, dao , services and end point.
#Entity
#Table(name="country")
public class Country implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="id")
private int id;
#Column(name="countryName")
private String countryName;
#OneToMany(mappedBy = "countyId",cascade = CascadeType.ALL)
private Set<States> states;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
public Set<States> getStates() {
return states;
}
public void setStates(Set<States> states) {
this.states = states;
}
}
My state class:
#Entity
#Table(name="states")
public class States implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="id")
private int id;
#ManyToOne
#JoinColumn(name="countyId")
private Country countyId;
#Column(name="stateName")
private String stateName;
#OneToMany(mappedBy = "states", cascade = CascadeType.ALL)
private Set<City> city;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Country getCountyId() {
return countyId;
}
public void setCountyId(Country countyId) {
this.countyId = countyId;
}
public String getStateName() {
return stateName;
}
public void setStateName(String stateName) {
this.stateName = stateName;
}
public Set<City> getCity() {
return city;
}
public void setCity(Set<City> city) {
this.city = city;
}
}
My city class:
#Entity
#Table(name="cities")
public class City implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="id")
private int id;
#ManyToOne
#JoinColumn(name="stateId")
private States states;
#Column(name="cityName")
private String cityName;
#Column(name="zip")
private String zip;
public void setId(int id) {
this.id = id;
}
public void setZip(String zip) {
this.zip = zip;
}
public States getStates() {
return states;
}
public void setStates(States states) {
this.states = states;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public String getZip() {
return zip;
}
public int getId() {
return id;
}
}
My DAO:
#Transactional
#Repository
public class GSTCityDAO implements IGSTCityDAO {
#PersistenceContext
private EntityManager entityManager;
//#SuppressWarnings("unchecked")
#Override
public List<City> getAllCities() {
//Session session = sessionFactory.getCurrentSession();
String hql = "FROM City as ct ORDER BY ct.id";
List<City> l = entityManager.createQuery(hql,City.class).getResultList();
return l;
}
#Override
public City getCityById(int cityId) {
return entityManager.find(City.class, cityId);
}
#SuppressWarnings("unchecked")
#Override
public List<City> getCityByStateId(States stateId) {
String getcitybystate = " FROM City as c WHERE c.states = ?";
return (List<City>) entityManager.createQuery(getcitybystate).setParameter(1, stateId).getResultList();
}
#Override
public void addCity(City city) {
entityManager.persist(city);
}
#Override
public void updateCity(City city) {
City cityctl = getCityById(city.getId());
cityctl.setCityName(city.getCityName());
cityctl.setZip(city.getZip());
cityctl.setStates(city.getStates());
entityManager.flush();
}
#Override
public void deleteCity(int cityId) {
entityManager.remove(getCityById(cityId));
}
#Override
public boolean cityExists(String name, String zip) {
String hql = "FROM City WHERE cityName = ? and zip = ?";
int count = entityManager.createQuery(hql).setParameter(1,name).setParameter(2, zip).getResultList().size();
return count > 0 ? true : false;
}
}
Services:
#Service
public class GSTCityService implements IGSTCityService {
#Autowired
private IGSTCityDAO cityDAO;
#Override
public List<City> getAllCities() {
List<City> l = cityDAO.getAllCities();
Hibernate.initialize(l);
return l;
}
public List<City> getCityByStateId(States stateId) {
return cityDAO.getCityByStateId(stateId);
}
#Override
public City getCityById(int cityId) {
City city = cityDAO.getCityById(cityId);
return city;
}
#Override
public synchronized boolean addCity(City city) {
if(cityDAO.cityExists(city.getCityName(), city.getZip())){
return false;
}else{
cityDAO.addCity(city);
return true;
}
}
#Override
public void updateCity(City city) {
cityDAO.updateCity(city);
}
#Override
public void deleteCity(int cityId) {
cityDAO.deleteCity(cityId);
}
}
End Point:
#Component
#Path("/")
public class Test {
private static final Logger logger = LoggerFactory.getLogger(Test.class);
#Autowired
private IGSTCityService cityService;
#GET
#Path("/hi")
#Produces(MediaType.APPLICATION_JSON)
public Response hello(){
return Response.ok("Hello GST").build();
}
#GET
#Path("/test")
#Produces(MediaType.APPLICATION_JSON)
public Response getAllDate(){
List<City> list = cityService.getAllCities();
for(City city: list){
System.out.println(city);
}
return Response.ok(list).build();
}
#GET
#Path("/test/{id}")
#Produces(MediaType.APPLICATION_JSON)
public Response getAllDateBySome(#PathParam("id") Integer id){
States state = new States();
state.setId(id);
List<City> list = cityService.getCityByStateId(state);
return Response.ok(list).build();
}
#GET
#Path("/{id}")
#Produces(MediaType.APPLICATION_JSON)
public Response getDataById(#PathParam("id")Integer id){
City citl = cityService.getCityById(id);
return Response.ok(citl).build();
}
#POST
#Path("/add")
#Consumes(MediaType.APPLICATION_JSON)
public Response addData(City city){
boolean isAdded = cityService.addCity(city);
if(!isAdded){
return Response.status(Status.CONFLICT).build();
}
return Response.created(URI.create("/gst/"+ city.getId())).build();
}
#PUT
#Path("/update")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Response updateCountry(City city){
cityService.updateCity(city);
return Response.ok(city).build();
}
#DELETE
#Path("/{id}")
#Consumes(MediaType.APPLICATION_JSON)
public Response deleteCountry(#PathParam("id")Integer id){
cityService.deleteCity(id);
return Response.noContent().build();
}
}
I am using import org.springframework.transaction.annotation.Transactional; for transnational in DAO. Also I can not use #PersistenceContext(type=PersistenceContextType.EXTENDED) and fetch type Eager because I get error of Maximum stack size exceeded
I solved it by using the #JsonBackReference on OneToMany relationship. The problem is with the Serialization and Deserialization.
" the property annotated with #JsonManagedReference annotation is handled normally (serialized normally, no special handling for deserialization) and the property annotated with #JsonBackReference annotation is not serialized; and during deserialization, its value is set to instance that has the "managed" (forward) link."
You should do one or both of the following:
1) Move the #Transactional from DAO to Service. Thats a good idea in general as usually are still processing the result entities in some way on that layer.
2) Fetch the dependencies in the queries explicitly:
select ct FROM City as ct inner join fetch ct.states s ORDER BY ct.id
I read a CSV file with university courses (11000 rows) and want to insert this using hibernate into a MySQL database. The problem is that hibernate inserts each row twice. There is a bug regarding this issue. Solution should be to flush each child after persisting.
See here: Hibernate inserts duplicates into a #OneToMany collection and https://hibernate.atlassian.net/browse/HHH-6776
Here is the code from my Spring applications controller:
#RequestMapping(value = "/readcsv")
public String readCSVFile() {
entityManager.setFlushMode(FlushModeType.COMMIT);
//Load all courses and universities and add to hashmap for fast lookup.
ArrayList<Course> allCourses = (ArrayList) entityManager.createQuery("FROM Course").getResultList();
MultiValueMap courseMap = MultiValueMap.decorate(new HashMap<String, Course>());
for (Course c : allCourses) {
courseMap.put(c.getName(), c);
}
ArrayList<University> allUniversities = (ArrayList) entityManager.createQuery("FROM University").getResultList();
HashMap<String, University> universityMap = new HashMap<String, University>();
for (University u : allUniversities) {
universityMap.put(u.getName(), u);
}
Country sweden = (Country) entityManager.createQuery("SELECT c FROM Country c WHERE c.name = 'Sweden'").getSingleResult();
ArrayList<Course> coursesToAdd = new ArrayList<Course>();
//Set fixed parameters for this specific dataset.
String filename = "/Volumes/320gb/macbookpro/Documents/AntagningsstatistikVT2015.csv";
String semester = "Spring2015";
String type = "Classroom";
int pace = 100;
University u;
try {
//Read file
File fileDir = new File(filename);
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(fileDir), "UTF-8"));
String line;
//Loop lines in file
while ((line = in.readLine()) != null) {
// use comma as separator
String[] courseLine = line.split(",");
String name = courseLine[1];
String university = courseLine[2];
//See if the course is already in the database
Collection<Course> coursesWithSameName = courseMap.getCollection(name);
boolean found = false;
if (coursesWithSameName != null) {
for (Course course: coursesWithSameName) {
if (course.getUniversity().getName().equals(university)) {
System.out.println("COURSE ALREADY IN DB : " + name + " " + university);
found = true;
}
}
}
//If not, insert it
if (found == false) {
if (!universityMap.containsKey(university)) {
u = new University();
u.setName(university);
u.setCountry(sweden);
u.setUserAdded(false);
universityMap.put(u.getName(), u);
entityManager.persist(u);
entityManager.flush();
} else {
u = universityMap.get(university);
}
Course course = new Course();
course.setName(name);
course.setUniversity(u);
course.setType(type);
course.setPace(pace);
course.setSemester(semester);
courseMap.put(course.getName(), course);
coursesToAdd.add(course);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("NUMBER OF ROWS IN coursesToAdd : " + coursesToAdd.size()); //Correctly prints 11000
for (Course course : coursesToAdd) { //inserts 22000 rows to db.
entityManager.persist(course);
entityManager.flush();
}
return "redirect:/";
}
Even though I flush after each persist double rows gets inserted. I have the #Transactional annotation on the controller class, is this the reason flush doesn't solve the problem? It however seems much slower when having flush there, which seems like it runs correctly compared to when it does a bulk insert on the end without flushing each insert.
Someone have a clue what is wrong in my code?
Thank you!
Edit:
Added University and Course entities:
Course:
import com.courseportal.project.account.Account;
import com.courseportal.project.utils.AbstractTimestampEntity;
import org.hibernate.annotations.Cascade;
import java.io.Serializable;
import java.util.List;
import javax.persistence.*;
#Entity
#Table(name="courses")
public class Course extends AbstractTimestampEntity implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
private long id;
#Column(name = "code")
private String code;
#Column(name = "name")
private String name;
#OneToMany(cascade = CascadeType.ALL)
#OrderBy("date desc")
private List<CourseRank> ranks;
#OneToMany(cascade = CascadeType.ALL)
#OrderBy("date desc")
private List<Comment> comments;
#OneToMany(cascade = CascadeType.ALL)
#OrderBy("date desc")
private List<UserBook> userBooks;
#ElementCollection
private List<CourseBook> courseBooks;
#ManyToMany
#JoinTable(name="courses_enrolledStudents")
private List<Account> enrolledStudents;
#OneToMany(cascade = CascadeType.ALL)
private List<Timeslot> times;
#ManyToOne
private University university;
/*
* fall
* spring
* summer
*/
private String semester;
private String teacherName;
private String courseLink;
private String requirementsLink;
/**
* Undergraduate
* Graduate
*/
private String level;
/**
* Online (MOOC - Massive Open Online Courses)
* Classroom (Traditional)
* Mixed (Lab)
*/
private String type;
/**
* How fast the course going in percentage.
*/
private int pace;
private int numberOfAssignments;
private int numberOfProjects;
private int numberOfExams;
private double credits;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public University getUniversity() {
return university;
}
public void setUniversity(University university) {
this.university = university;
}
public String getCourseLink() {
return courseLink;
}
public void setCourseLink(String courseLink) {
this.courseLink = courseLink;
}
public String getRequirementsLink() {
return requirementsLink;
}
public void setRequirementsLink(String requirementsLink) {
this.requirementsLink = requirementsLink;
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
public List<Timeslot> getTimes() {
return times;
}
public void setTimes(List<Timeslot> times) {
this.times = times;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getPace() {
return pace;
}
public void setPace(int pace) {
this.pace = pace;
}
public String getTeacherName() {
return teacherName;
}
public void setTeacherName(String teacherName) {
this.teacherName = teacherName;
}
public List<Comment> getComments() {
return comments;
}
public void setComments(List<Comment> comments) {
this.comments = comments;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<CourseRank> getRanks() {
return ranks;
}
public void setRanks(List<CourseRank> ranks) {
this.ranks = ranks;
}
public void addRank(CourseRank rank) {
this.ranks.add(rank);
}
public void removeRank(CourseRank rank) {
this.ranks.remove(rank);
}
public void addComment(Comment comment) {
comments.add(comment);
}
//User books, books that are for sale getters and setters
public void removeUserBook(UserBook book) {
this.userBooks.remove(book);
}
public void addUserBook(UserBook book) {
this.userBooks.add(book);
}
public List<UserBook> getUserBooks() {
return userBooks;
}
public void setUserBooks(List<UserBook> userBooks) {
this.userBooks = userBooks;
}
public List<CourseBook> getCourseBooks() {
return courseBooks;
}
public void setCourseBooks(List<CourseBook> courseBooks) {
this.courseBooks = courseBooks;
}
public void removeCourseBook(CourseBook book) {
this.courseBooks.remove(book);
}
public void addCourseBook(CourseBook book) {
this.courseBooks.add(book);
}
public int getNumberOfAssignments() {
return numberOfAssignments;
}
public void setNumberOfAssignments(int numberOfassignments) {
this.numberOfAssignments = numberOfassignments;
}
public int getNumberOfProjects() {
return numberOfProjects;
}
public void setNumberOfProjects(int numberOfprojects) {
this.numberOfProjects = numberOfprojects;
}
public int getNumberOfExams() {
return numberOfExams;
}
public void setNumberOfExams(int numberOfexams) {
this.numberOfExams = numberOfexams;
}
public double getCredits() {
return credits;
}
public void setCredits(double credits) {
this.credits = credits;
}
public List<Account> getEnrolledStudents() {
return enrolledStudents;
}
public void setEnrolledStudents(List<Account> enrolledStudents) {
this.enrolledStudents = enrolledStudents;
}
public void addEnrolledStudent(Account student) {
this.enrolledStudents.add(student);
}
public void removeEnrolledStudent(Account student) {
this.enrolledStudents.remove(student);
}
public String getSemester() {
return semester;
}
public void setSemester(String semester) {
this.semester = semester;
}
}
And University:
import com.courseportal.project.utils.AbstractTimestampEntity;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name="universities")
public class University extends AbstractTimestampEntity implements Serializable {
#Id
#GeneratedValue
private int id;
private String name;
#ManyToOne
private Country country;
private boolean userAdded;
public University() {}
public University(String university) {
name = university;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isUserAdded() {
return userAdded;
}
public void setUserAdded(boolean userAdded) {
this.userAdded = userAdded;
}
}