I write my first java application to read rss stream and use spring, spring-data, hibernate.
My models.
RssFeed:
#Entity(name = "RssFeed")
#Table(name = "FEED")
#JsonIgnoreProperties({"rssChannel"})
public class RssFeed {
#Id
#GeneratedValue
#Column
private Integer id;
#Column(unique = true)
#Index(name = "title_index")
private String title;
#Column
#URL
private String link;
#Column
private String description;
#Column
private String content;
#Column
#Temporal(TemporalType.TIMESTAMP)
private Date pubDate;
#Column
#Temporal(TemporalType.TIMESTAMP)
private Date updateDate;
#ManyToOne
#JoinColumn(name = "channelId")
private RssChannel rssChannel;
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinTable(name = "feed_category",
joinColumns = {#JoinColumn(name = "feed_id", nullable = false, updatable = false)},
inverseJoinColumns = {#JoinColumn(name = "category_id", nullable = false, updatable = false)})
private Set<RssCategory> rssCategories = new LinkedHashSet<RssCategory>();
}
RssChannel:
#Entity(name = "RssChannel")
#Table(name = "Channel",
uniqueConstraints = #UniqueConstraint(columnNames = {"link"}))
#JsonIgnoreProperties({"feeds"})
public class RssChannel implements Serializable{
#Id
#GeneratedValue
#Column
private Integer id;
#Column
private String title;
#Column(unique = true)
#org.hibernate.validator.constraints.URL
private String link;
#Column
#org.hibernate.validator.constraints.URL
private String image;
#Column
private String description;
#OneToMany(mappedBy = "rssChannel", cascade = CascadeType.ALL, orphanRemoval = true)
private List<RssFeed> feeds = new LinkedList<RssFeed>();
}
And RssCategory:
#Entity(name = "RssCategory")
#Table(name = "CATEGORY")
#JsonIgnoreProperties({"rssFeeds"})
public class RssCategory {
#Id
#GeneratedValue
#Column
private Integer id;
#Column(unique = true)
private String title;
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "rssCategories")
public Set<RssFeed> rssFeeds = new LinkedHashSet<RssFeed>();
}
I use CrudRepository for manipulation with data. When save RssFeed without many to many it`s ok:
RssChannel channel = rssChannelService.get(url.toString());
rssFeed.setRssChannel(channel);
rssFeedService.save(rssFeed);
But when i add RssCategory:
rssCategory rssCategory = rssCategoryService.findOrCreate("test");
rssFeed.getRssCategories().add(rssCategory);
rssFeedService.save(rssFeed);
get exception: rg.hibernate.PersistentObjectException: detached entity passed to persist: RssCategory.
My RssFeedServiceImpl:
#Service
public class RssFeedServiceImpl implements RssFeedService {
#Autowired
private RssChannelDAO rssChannelDAO;
#Autowired
private RssFeedDAO rssFeedDAO;
#Override
public Page<RssFeed> findAll(Pageable pageable) {
return rssFeedDAO.findAll(pageable);
}
#Override
public Page<RssFeed> findAll(int rssChannelId, Pageable pageable) {
RssChannel rssChannel = rssChannelDAO.findOne(rssChannelId);
return rssFeedDAO.findByRssChannel(rssChannel, pageable);
}
#Override
public RssFeed get(String title) {
return rssFeedDAO.findByTitle(title);
}
#Override
public RssFeed save(RssFeed rssFeed) {
return rssFeedDAO.save(rssFeed);
}
}
And RssCategoryServiceImpl:
#Service
public class RssCategoryServiceImpl implements RssCategoryService {
#Autowired
RssCategoryDAO rssCategoryDAO;
#Override
public RssCategory findOrCreate(String title) {
RssCategory category = rssCategoryDAO.findByTitle(title);
if (category == null) {
category = new RssCategory();
category.setTitle(title);
category = rssCategoryDAO.save(category);
}
return category;
}
}
How save many to many?
You probably need to save your RssCategory first, in order to have an ID to store in feed_category table. This last save will be automatically made when you make the assignment:
rssFeed.getRssCategories().add(rssCategory);
but first you need to do:
rssFeedService.save(rssCategory);
Probably you'll need to put this operations within a transaction.
Related
I am working on a Spring Boot project using Spring Data JPA trying to adopt the "query by method name" style in order to define my queries into repositories.
I am finding some difficulties trying to implement a select query retrieving the list of objects based on two different "where condition". I will try to explain what I have to do.
First of all this is my main entity class named Wallet:
#Entity
#Table(name = "wallet")
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Wallet implements Serializable {
private static final long serialVersionUID = 6956974379644960088L;
#Id
#Column(name = "id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
#Column(name = "address")
private String address;
#Column(name = "notes")
private String notes;
#ManyToOne
#EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
#JoinColumn(name = "fk_user_id", referencedColumnName = "id")
#JsonBackReference(value = "user-wallets")
private User user;
#ManyToOne
#EqualsAndHashCode.Exclude // Needed by Lombock in "Many To One" relathionship to avoid error
#JoinColumn(name = "fk_coin_id", referencedColumnName = "id")
private Coin coin;
#ManyToOne
#JoinColumn(name = "type", referencedColumnName = "id")
private WalletType walletType;
public Wallet(String address, String notes, User user, Coin coin, WalletType walletType) {
super();
this.address = address;
this.notes = notes;
this.user = user;
this.coin = coin;
this.walletType = walletType;
}
}
As you can see a wallet is directly binded to a specific User object and to a specific Coin object.
For completeness this is the code of my User entity class:
#Entity
#Table(name = "portal_user")
#Getter
#Setter
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class User implements Serializable {
private static final long serialVersionUID = 5062673109048808267L;
#Id
#Column(name = "id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
#Column(name = "first_name")
#NotNull(message = "{NotNull.User.firstName.Validation}")
private String firstName;
#Column(name = "middle_name")
private String middleName;
#Column(name = "surname")
#NotNull(message = "{NotNull.User.surname.Validation}")
private String surname;
#Column(name = "sex")
#NotNull(message = "{NotNull.User.sex.Validation}")
private char sex;
#Column(name = "birthdate")
#NotNull(message = "{NotNull.User.birthdate.Validation}")
private Date birthdate;
#Column(name = "tax_code")
#NotNull(message = "{NotNull.User.taxCode.Validation}")
private String taxCode;
#Column(name = "e_mail")
#NotNull(message = "{NotNull.User.email.Validation}")
private String email;
#Column(name = "pswd")
#NotNull(message = "{NotNull.User.pswd.Validation}")
private String pswd;
#Column(name = "contact_number")
#NotNull(message = "{NotNull.User.contactNumber.Validation}")
private String contactNumber;
#Temporal(TemporalType.DATE)
#Column(name = "created_at")
private Date createdAt;
#Column(name = "is_active")
private boolean is_active;
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "user", orphanRemoval = true)
#JsonManagedReference(value = "address")
private Set<Address> addressesList = new HashSet<>();
#ManyToMany(cascade = { CascadeType.MERGE })
#JoinTable(
name = "portal_user_user_type",
joinColumns = { #JoinColumn(name = "portal_user_id_fk") },
inverseJoinColumns = { #JoinColumn(name = "user_type_id_fk") }
)
private Set<UserType> userTypes;
#ManyToOne(fetch = FetchType.LAZY)
#JsonProperty("subagent")
private User parent;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "user", orphanRemoval = true)
#JsonManagedReference(value = "user-wallets")
private Set<Wallet> wallets = new HashSet<>();
public User() {
super();
// TODO Auto-generated constructor stub
}
public User(String firstName, String middleName, String surname, char sex, Date birthdate, String taxCode,
String email, String pswd, String contactNumber, Date createdAt, boolean is_active) {
super();
this.firstName = firstName;
this.middleName = middleName;
this.surname = surname;
this.sex = sex;
this.birthdate = birthdate;
this.taxCode = taxCode;
this.email = email;
this.pswd = pswd;
this.contactNumber = contactNumber;
this.createdAt = createdAt;
this.is_active = is_active;
}
}
and this is the code of my Coin entity class:
#Entity
#Table(name = "coin")
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Coin implements Serializable {
private static final long serialVersionUID = 6956974379644960088L;
#Id
#Column(name = "id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
#Column(name = "name")
#NotNull(message = "{NotNull.Coin.name.Validation}")
private String name;
#Column(name = "description")
private String description;
#Column(name = "code", unique = true)
#NotNull(message = "{NotNull.Coin.code.Validation}")
private String code;
#Type(type="org.hibernate.type.BinaryType")
#Column(name = "logo")
private byte[] logo;
}
Then I have this WalletRepository interface:
public interface WalletRepository extends JpaRepository<Wallet, Integer> {
}
Here I need to define a query by name method that retrieve a specific wallet of a specific User (I think that I can query by the id field of the User) and based and related to a specific Coin (I think that I can query by the id fied of the Coin).
How can I implement a behavior like this?
The following should work:
public interface WalletRepository extends JpaRepository<Wallet, Integer> {
List<Wallet> findByUserIdAndCoinId();
}
You can read more about this at:
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repository-query-keywords
Problem
I am trying to store an object in my Postgres database. This consists of the Order.class, (List) OrderDevice.class, and a Department.class.
The important thing is that the OrderDevices are always stored new in the DB, but a Department may already exist.
When I try to save the object to my database using save I get the following error message: (shown below)
I get the error message "detached entity passed to persist: com.niclas.model.OrderDevice" if the department does not exist yet, if the department exists the error message looks like this: "detached entity passed to persist: com.niclas.model.Department".
Solution attempts
This solution cannot be used because I do not use bidirectional mapping.
(I don't want to use a bidirectional mapping because I want to access the departments without an order.)
I also tried to change the Cascade types to MERGE like in this solution
I also tried using #Transactional on the method
I also tried to save the children in the database first and then the parent like this:
departmentRepository.save(order.getDepartment()); orderDeviceRepository.saveAll(order.getDevices()); orderRepository.save(order);
I hope I have described my good enough and I am happy about suggestions for solutions
Error.log
The log can be viewed here. (The formatting did not work here)
Order.class
#Entity
#Table(name = "orders")
public class Order extends AuditModel {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.AUTO) //TODO better config for GenerationType
private long id;
#Column(name = "order_id")
private String orderId;
#Column(name = "department_id")
private long departmentId;
#OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name = "department", referencedColumnName = "id")
private Department department;
#JsonProperty("deviceList")
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name = "order_id", referencedColumnName = "order_id")
private List<OrderDevice> devices;
#JsonProperty("forename")
#Column(name = "sender_forename")
private String senderForename;
#JsonProperty("surname")
#Column(name = "sender_surname")
private String senderSurname;
#Column(name = "notes", columnDefinition = "TEXT")
private String notes;
#Column(name = "month")
private int month;
#Column(name = "year")
private int year;
public Order() {
}
... Getter/Setters
}
OrderDevice.class
#Entity
#Table(name = "order_devices")
public class OrderDevice extends AuditModel{
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.AUTO) //TODO better config for GenerationType
private long id;
#Column( name = "order_id", insertable = false, updatable = false )
private String orderId;
#Column(name = "device_id")
private long deviceId;
#Column(name = "device_name")
private String deviceName;
#Column(name = "priceName")
private String priceName;
#Column(name = "price")
private double price;
#Column(name = "count")
private int count;
public OrderDevice() {
}
... Getters/Setters
}
Department.class
#Entity
#Table(name = "departments")
public class Department {
//TODO add Form Validation
//TODO better Naming for From Attributes on Frontend and Backend
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.AUTO) //TODO better config for GenerationType
private long id;
#Column(name = "department_name")
private String department;
#Column(name = "contact_person_forename")
private String forename;
#Column(name = "contact_person_surname")
private String surname;
#Column(name = "contact_person_mail")
private String mail;
#Column(name = "street")
private String street;
#Column(name = "house_number")
private String houseNumber;
#Column(name = "location")
private String location;
#Column(name = "postal_code")
private int postalCode;
#Column(name = "country")
private String country;
#Column(name = "auto_send_invoice")
private boolean autoSend;
#Column(name = "registered")
private boolean registered;
public Department() {
}
... Getter/Setters
}
OrderController.class
#Slf4j
#RestController
public class OrderController {
private final DepartmentRepository departmentRepository;
private final OrderRepository orderRepository;
private final OrderDeviceRepository orderDeviceRepository;
public OrderController(OrderRepository orderRepository, DepartmentRepository departmentRepository,
OrderDeviceRepository orderDeviceRepository) {
this.orderRepository = orderRepository;
this.departmentRepository = departmentRepository;
this.orderDeviceRepository = orderDeviceRepository;
}
#PostMapping("/orders/add")
public ResponseEntity<Order> addDepartment(#RequestBody Order order) throws JsonProcessingException {
order.setOrderId(order.generateOrderId());
DateTime dateTime = new DateTime();
order.setMonth(dateTime.getMonthOfYear());
order.setYear(dateTime.getYear());
order.getDevices().forEach(orderDevice -> {
orderDevice.setOrderId(order.getOrderId());
});
//departmentRepository.save(order.getDepartment());
//orderDeviceRepository.saveAll(order.getDevices());
orderRepository.save(order);
return new ResponseEntity<>(order, HttpStatus.CREATED);
}
Update
If the objects are created in this way, no error will occur and the order will be successfully saved in the database.
However, I don't understand why it works this way and not via ObjectMapper. Does anyone know why?
#PostMapping("/orders/add")
public ResponseEntity<Order> addDepartment(#RequestBody JsonNode jsonNode) throws JsonProcessingException {
Order order = new Order();
JsonNode departmentJson = jsonNode.get("department");
Department department;
if ( departmentJson.get("id").canConvertToInt() ) {
department = departmentRepository.findDepartmentById(departmentJson.get("id").asInt());
} else {
department = new Department();
department.setDepartment(departmentJson.get("department").asText());
department.setForename(departmentJson.get("forename").asText());
department.setSurname(departmentJson.get("surname").asText());
department.setMail(departmentJson.get("mail").asText());
department.setStreet(departmentJson.get("street").asText());
department.setHouseNumber(departmentJson.get("houseNumber").asText());
department.setLocation(departmentJson.get("location").asText());
department.setPostalCode(departmentJson.get("postalCode").asInt());
department.setCountry(departmentJson.get("country").asText());
department.setAutoSend(departmentJson.get("autoSend").asBoolean());
department.setRegistered(departmentJson.get("registered").asBoolean());
}
order.setDepartment(department);
order.setOrderId(order.generateOrderId());
order.setDepartmentId(department.getId());
List<OrderDevice> orderDevices = new ArrayList<>();
JsonNode devices = jsonNode.get("deviceList");
for (JsonNode node : devices) {
//TODO replace this mess with objectMapper
if (node.has("count") && node.get("count").asInt() != 0){
OrderDevice device = new OrderDevice();
device.setOrderId(order.getOrderId());
device.setDeviceId(node.get("id").asLong());
device.setDeviceName(node.get("deviceName").asText());
device.setPriceName(node.get("priceName").asText());
device.setPrice(node.get("price").asDouble());
device.setCount(node.get("count").asInt());
orderDevices.add(device);
}
}
order.setDevices(orderDevices);
order.setSenderForename(jsonNode.get("forename").asText());
order.setSenderSurname(jsonNode.get("surname").asText());
order.setNotes(jsonNode.get("notes").asText());
DateTime dateTime = new DateTime();
order.setMonth(dateTime.getMonthOfYear());
order.setYear(dateTime.getYear());
orderRepository.save(order);
return new ResponseEntity<>(order, HttpStatus.CREATED);
}
You can try to use instead of orderRepository.save(order) use orderRespostiory.saveOrUpdate(order).
I've been having some difficulties implementing an extra column in a many-to-many relationship using jpa and hibernate.
I've already tried many times but didn't succeed. The only way I've got things to work was with a simple many-to-many relationship, with no extra columns and no new entity created. The code I've given below it's working but it doesn't include the extra entity desired, called "CandidateLanguage", so I can add an extra attribute.
//CANDIDATE CLASS
//imports
#Entity
#Table(name="candidates")
#EntityListeners(AuditingEntityListener.class)
#JsonIgnoreProperties(value = {"createdat", "updatedat"}, allowGetters =
true)
public class Candidate {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private String fullname;
private String address;
private String birthdate;
private String placeofbirth;
private String hobbies;
private String presentation;
private int yearsofexperience;
#Column(nullable = false, updatable = false)
#Temporal(TemporalType.TIMESTAMP)
#CreatedDate
private Date createdat;
#Column(nullable =false)
#Temporal(TemporalType.TIMESTAMP)
#LastModifiedDate
private Date updatedat;
public Candidate(String fullname, String address, String birthdate, String placeofbirth, String hobbies, String presentation, int yearsofexperience) {
this.fullname = fullname;
this.address = address;
this.birthdate = birthdate;
this.placeofbirth = placeofbirth;
this.hobbies = hobbies;
this.presentation = presentation;
this.yearsofexperience = yearsofexperience;
}
#ManyToMany(fetch = FetchType.EAGER,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
#JoinTable(name = "candidate_languages",
joinColumns = { #JoinColumn(name = "candidate_id") },
inverseJoinColumns = { #JoinColumn(name = "language_id") })
private Set<Language> languages = new HashSet<>();
//getters and setters
//LANGUAGE CLASS
//imports
#Entity
#Table(name="languages")
#EntityListeners(AuditingEntityListener.class)
public class Language {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
#NaturalId
private String idiom;
#ManyToMany(fetch = FetchType.EAGER,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
},
mappedBy = "languages")
private Set<Candidate> candidates = new HashSet<>();
public Language() {
}
public Language(String idiom) {
this.idiom = idiom;
}
//getters and setters
The objective is to persist another column called "writting", which is a skill level in terms of language knowledge and has levels "C1", "C2", "B1", "B2", "A1", "A2" and "Native" (maybe an enumerated?).
Thanks in advance!
I have a rest api that accept POST to save Candidates.
This the Object coming from POST:
{
"name": "renato",
"email":"rena#gmail.com",
"github":"renato.github.com",
"languages":[{"name":"Java"}],
"frameworks":[{"name":"Spring"}],
"linkedin":"renato.linkedin.com",
"motto":"the best",
"password":"1234"
}
then I do a Call to persist:
#Transactional
#Override
public boolean addCandidate(Candidate candidate) {
if (candidateRepository.findCandidateByEmail(candidate.getEmail()) == null) {
candidateRepository.save(candidate);
return true;
} else {
return false;
}
}
When trying to save (automatically) the Languages and the Frameworks, I would like to check in database if there's already a entry, and if exists, update only
the correspondent relational table.
Here's the Pojos:
CANDIDATE:
#Entity
#Table(name = "candidates")
public class Candidate {
#Id
#Column(name = "candidate_id")
#GeneratedValue
private Long cadet_Id;
#Column (name = "email")
private String email;
#Column (name = "name")
private String name;
#Column(name = "password")
private String password;
#Column (name = "motto")
private String motto;
#Column (name = "github")
private String github;
#Column (name = "linkedin")
private String linkedin;
#ManyToMany (cascade = {CascadeType.ALL})
#JoinTable(name = "candidate_languages",
joinColumns = #JoinColumn(name = "language_id"),
inverseJoinColumns = #JoinColumn(name = "candidate_id"))
private Set<Languages> languages;
#ManyToMany (cascade = {CascadeType.ALL})
#JoinTable(name = "candidate_frameworks",
joinColumns = #JoinColumn(name = "framework_id"),
inverseJoinColumns = #JoinColumn(name = "candidate_id"))
private Set<Frameworks> frameworks;
LANGUAGES
#Entity
#Table(name = "languages")
public class Languages {
#Id
#Column(name = "language_id")
#GeneratedValue
private Long language_Id;
#Column (name = "name")
private String name;
FRAMEWORKS:
#Entity
#Table(name = "Frameworks")
public class Frameworks {
#Id
#Column(name = "framework_id")
#GeneratedValue
private Long framework_Id;
#Column (name = "name", unique = true)
private String name;
I'm Using spring data and the default Repositorys for each class:
public interface FrameworkRepository extends CrudRepository<Frameworks,Long{}
Thanks for the help.
I have a following error:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`spindledb`.`section`, CONSTRAINT `FK_ftoru9cp83n512p9is8x3vo53` FOREIGN KEY (`scenario_id`) REFERENCES `scenario` (`scenario_id`))
Here are my classes:
Scenario:
#Entity
#Table(name = "scenario")
public class Scenario {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "scenario_id")
private int id;
#Column(name = "title", nullable = false)
private String title;
#NotNull
#DateTimeFormat(pattern = "dd/MM/yyyy")
#Column(name = "creation_date", nullable = false)
#Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
private LocalDate creationDate;
#ManyToOne
#LazyCollection(LazyCollectionOption.FALSE)
#JoinColumn(name = "id", nullable = false)
private User user;
#OneToMany(mappedBy = "scenario", orphanRemoval = true)
#LazyCollection(LazyCollectionOption.FALSE)
private Set<Plot> plotList = new HashSet<Plot>();
#OneToMany(mappedBy = "scenario", orphanRemoval = true)
#LazyCollection(LazyCollectionOption.FALSE)
private Set<Character> characterList = new HashSet<Character>();
#OneToMany(mappedBy = "scenario", cascade=CascadeType.ALL, orphanRemoval = true)
#LazyCollection(LazyCollectionOption.FALSE)
#OrderBy("sequence ASC")
private Set<Section> sectionList = new HashSet<Section>();
Section:
#Entity
#Table(name = "section")
public class Section {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "section_id")
private int id;
#Size(min = 4, max = 50)
#NotNull
#Column(name = "name")
private String name;
#NotNull
#Column(name = "type")
private String type = SectionType.TEXT.getSectionType();
#Column(name = "visibility")
private boolean visibility;
#NotNull
#Column(name = "sequence")
private int sequence;
#ManyToOne (cascade=CascadeType.ALL)
#LazyCollection(LazyCollectionOption.FALSE)
#JoinColumn(name = "scenario_id", nullable = false)
private Scenario scenario;
Controller:
#RequestMapping(value = { "/delete-{id}-scenario" }, method = RequestMethod.GET)
public String deleteScenario(#PathVariable int id) {
scenarioService.deleteScenarioById(id);
return "redirect:/home";
}
Scenario service:
#Service("scenarioService")
#Transactional
public class ScenarioServiceImpl implements ScenarioService {
#Autowired
private ScenarioDao dao;
#Override
public Scenario findById(int id) {
return dao.findById(id);
}
#Override
public void saveScenario(Scenario scenario) {
dao.saveScenario(scenario);
}
public void updateScenario(Scenario scenario) {
Scenario entity = dao.findById(scenario.getId());
if(entity!=null){
entity.setTitle(scenario.getTitle());
entity.setCreationDate(scenario.getCreationDate());
}
}
#Override
public void deleteScenarioById(int id) {
dao.deleteScenarioById(id);
}
Dao
#Repository("scenarioDao")
public class ScenarioDaoImpl extends AbstractDao<Integer, Scenario> implements ScenarioDao {
#Override
public Scenario findById(int id) {
return getByKey(id);
}
#Override
public void saveScenario(Scenario scenario) {
persist(scenario);
}
#Override
public void deleteScenarioById(int id) {
Query query = getSession().createSQLQuery("delete from scenario where id = :id");
query.setString("id", ""+id);
query.executeUpdate();
}
I understand that the problem is that there may be a Section that can not exist without scenario. Right now however section table in database is empty and I still can't remove Scenario. Thanks for advice
Deleting an entity via Query would bypass any Cascade settings you put via annotation.
I would suggest find the entity first by id, then delete the entity object:
Object scenario = session.load(Scenario.class, id);
if (scenario != null) {
session.delete(scenario);
}
use cascade=CascadeType.ALL with all #ManyToOne relations in class Scenario because if you are going to delete any Scenario from database it must not be referenced any where in data base.
the other way to delete is.
Serializable id = new Long(1); //your id
Object persistentInstance = session.load(Scenario.class, id);
if (persistentInstance != null) {
session.delete(persistentInstance);
}