How to check if Node already exists neo4j before creating a new one - spring-boot

I am working on an Spring boot + Neo4j application & I am new to graphDb.
Problem I am facing is described below,
I want to create unique (Priviledge) node pointing(In relation) to UserRole Node.
In below image you can see duplicate (Priviledge) node is created
how can I write a custom cypher to check Priviledge if exist before saving a new one
UserRole Domain:
#NodeEntity
public class UserRole {
public UserRole(User user, Role role) {
this.user = user;
this.role = role;
}
/**
For Jackson Parsing
**/
public UserRole() {
}
#GraphId
private Long id;
public UserRole(User user, Role role, Unit unit) {
this.user = user;
this.role = role;
this.unit = unit;
}
public long getId() {
return id;
}
#Relationship(type = HAS_USERROLE,direction = "OUTGOING")
User user;
public User getUser() {
return user;
}
#Relationship (type = HAS_ROLE_OF,direction = "OUTGOING")
Role role;
public Role getRole() {
return role;
}
#Relationship(type = "WORKS_IN",direction = "OUTGOING")
Unit unit;
public Unit getUnit() {
return unit;
}
public void setUnit(Unit unit) {
this.unit = unit;
}
#Relationship(type = "HAS_PRIVILEDGE", direction = "OUTGOING")
List<Priviledge> priviledgeList;
public List<Priviledge> getPriviledgeList() {
return priviledgeList;
}
public void setPriviledgeList(List<Priviledge> priviledgeList) {
this.priviledgeList = priviledgeList;
}
}
Priviledge Domain:
public class Priviledge {
#GraphId
Long id;
private String priviledge;
private String priviledgeOn;
private Long priviledgeOnId;
public Priviledge() {
}
public Priviledge(String priviledge, String priviledgeOn) {
this.priviledge = priviledge;
this.priviledgeOn = priviledgeOn;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getPriviledge() {
return priviledge;
}
public void setPriviledge(String priviledge) {
this.priviledge = priviledge;
}
public String getPriviledgeOn() {
return priviledgeOn;
}
public void setPriviledgeOn(String priviledgeOn) {
this.priviledgeOn = priviledgeOn;
}
public Long getPriviledgeOnId() {
return priviledgeOnId;
}
public void setPriviledgeOnId(Long priviledgeOnId) {
this.priviledgeOnId = priviledgeOnId;
}
}

As it can be found in the answer for this question, to update (and not create new instance) you have to use an ID of the node, when invoking save method.
Alternatively (as found in the comments of mentioned question) you should create you own query based on this documentation.

Related

Foregine key is not updating in spring boot Jpa

Basically, I am trying to establish a relationship between my two tables using spring boots.
And the relationship which I had used was the #onetoone and #onetomany relationship.
But after building the relationship and creating the table in MySQL whenever I run the program my foreign key is not updating.
The relationship is one user can have many contacts. I have tried unidirectional as well as bidirectional mapping but it is not working.
I want in contact table there will be a separate column for the foreign key. Based on that key I will show all contacts for that particular user.
This is my contact entity...
package com.example.jpa.contactEntities;
#Entity
#Table(name = "Contact")
public class ContactEntities {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long c_id;
private String c_name;
private String second_c_name;
private String c_work;
private String c_emali;
private String c_phone;
private String c_image;
#Column(length = 5000)
private String c_description;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "contact_id")
private UserEntities userEntities;
public ContactEntities() {
super();
}
public ContactEntities(long c_id, String c_name, String second_c_name, String c_work, String c_emali,
String c_phone, String c_image, String c_description, UserEntities userEntities) {
super();
this.c_id = c_id;
this.c_name = c_name;
this.second_c_name = second_c_name;
this.c_work = c_work;
this.c_emali = c_emali;
this.c_phone = c_phone;
this.c_image = c_image;
this.c_description = c_description;
this.userEntities = userEntities;
}
public long getC_id() {
return c_id;
}
public void setC_id(int c_id) {
this.c_id = c_id;
}
public String getC_name() {
return c_name;
}
public void setC_name(String c_name) {
this.c_name = c_name;
}
public String getSecond_c_name() {
return second_c_name;
}
public void setSecond_c_name(String second_c_name) {
this.second_c_name = second_c_name;
}
public String getC_work() {
return c_work;
}
public void setC_work(String c_work) {
this.c_work = c_work;
}
public String getC_emali() {
return c_emali;
}
public void setC_emali(String c_emali) {
this.c_emali = c_emali;
}
public String getC_phone() {
return c_phone;
}
public void setC_phone(String c_phone) {
this.c_phone = c_phone;
}
public String getC_image() {
return c_image;
}
public void setC_image(String c_image) {
this.c_image = c_image;
}
public String getC_description() {
return c_description;
}
public void setC_description(String c_description) {
this.c_description = c_description;
}
public UserEntities getUserEntities() {
return userEntities;
}
public void setUserEntities(UserEntities userEntities) {
this.userEntities = userEntities;
}
#Override
public String toString() {
return "ContactEntities [c_id=" + c_id + ", c_name=" + c_name + ", second_c_name=" + second_c_name + ", c_work="
+ c_work + ", c_emali=" + c_emali + ", c_phone=" + c_phone + ", c_image=" + c_image + ", c_description="
+ c_description + ", userEntities=" + userEntities + "]";
}
}
this is my user entity...
package com.example.jpa.userEntities;
#Entity
#Table(name = "UserEntities")
public class UserEntities {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long userId;
#NotBlank
#Size(min = 2, max = 20)
private String userName;
#NotBlank
#Column(unique = true)
#Email(regexp = "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+#[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$")
private String userEmail;
#NotNull(message = "password should not be blank")
private String userPass;
private boolean enable;
private String role;
#Column(length = 500)
private String userAbout;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "userEntities", orphanRemoval = true)
private List<ContactEntities> contactList = new ArrayList<>();
public UserEntities() {
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public long getUserId() {
return userId;
}
public void setUserId(long userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserEmail() {
return userEmail;
}
public void setUserEmail(String userEmail) {
this.userEmail = userEmail;
}
public String getUserPass() {
return userPass;
}
public void setUserPass(String userPass) {
this.userPass = userPass;
}
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public String getRoll() {
return role;
}
public void setRoll(String role) {
this.role = role;
}
public String getUserAbout() {
return userAbout;
}
public void setUserAbout(String userAbout) {
this.userAbout = userAbout;
}
public List<ContactEntities> getContactList() {
return contactList;
}
public void setContactList(List<ContactEntities> contactList) {
this.contactList = contactList;
}
#Override
public String toString() {
return "UserEntities [userId=" + userId + ", userName=" + userName + ", userEmail=" + userEmail + ", userPass="
+ userPass + ", enable=" + enable + ", role=" + role + ", userAbout=" + userAbout + ", contactList="
+ contactList + "]";
}
}
Repository of Contact
package com.example.jpa.repo;
import java.util.List;
import com.example.jpa.contactEntities.ContactEntities;
public interface ContactRepo extends JpaRepository<ContactEntities, Integer> {
#Query("from ContactEntities as c where c.userEntities.userId=:u_Id")
public List<ContactEntities> findContactsByUser(#Param("u_Id") long l);
}
Repository of User
package com.example.jpa.repo;
import com.example.jpa.userEntities.UserEntities;
#EnableJpaRepositories
public interface UserRepository extends JpaRepository<UserEntities, Integer> {
#Query("select u from UserEntities u where u.userEmail=:userEmail")
public UserEntities getUserByUserName(#Param("userEmail") String userEmail);
}
User controller
package com.example.jpa.controller;
#Controller
#RequestMapping("/user")
public class UserController {
#Autowired
private UserRepository userRepository;
#Autowired
private ContactRepo contactRepo;
#ModelAttribute
public void addCommonData(Model model, Principal principal) {
String username = principal.getName();
System.out.println("UserName:-" + username);
UserEntities userEntities = this.userRepository.getUserByUserName(username);
System.out.println("User:- " + userEntities);
model.addAttribute("userEntities", userEntities);
}
//dash board home
#RequestMapping("/index")
public String dashboard(Model model, Principal principal) {
return "normal/user_dashboard";
}
// open add form handler
#GetMapping("/add-contact")
public String openAddContactForm(Model model) {
model.addAttribute("title", "Add contact");
model.addAttribute("contactEntitie", new ContactEntities());
return "normal/add_contact";
}
// processing and contact form
#PostMapping("/upload")
public String processContact(#ModelAttribute ContactEntities contactEntitie,
#RequestParam("userImage") MultipartFile multipartFile, Principal principal, Model model,
HttpSession session) {
try {
model.addAttribute("contactEntitie", new ContactEntities());
String name = principal.getName();
UserEntities userEntities = userRepository.getUserByUserName(name);
userEntities.getContactList().add(contactEntitie);
// processing and uploading file....
if (multipartFile.isEmpty()) {
System.out.println("File is empty");
} else {
// upload the the file and update
contactEntitie.setC_image(multipartFile.getOriginalFilename());
File saveFile = new ClassPathResource("static/img").getFile();
// bring the folder path...
Path path = Paths
.get(saveFile.getAbsolutePath() + File.separator + multipartFile.getOriginalFilename());
Files.copy(multipartFile.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);
System.out.println("Image is uploaded");
}
userRepository.save(userEntities);
System.out.println("Datas are :" + contactEntitie);
// message success
session.setAttribute("message", new Messages("Your Contact is added !!! Add more...", "success"));
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
e.printStackTrace();
// error message
session.setAttribute("message", new Messages("Something went wrong !!! Try Again", "danger"));
}
return "normal/add_contact";
}
// show Contact handler
#GetMapping("/show-contacts")
public String showContact(Model model, Principal principal) {
model.addAttribute("title", "Show Contacts");
String userName = principal.getName();
UserEntities userEntities = userRepository.getUserByUserName(userName);
List<ContactEntities> contactList = contactRepo.findContactsByUser(userEntities.getUserId());
model.addAttribute("contactList", contactList);
return "normal/show_contacts";
}
}
All configuration class
User Details configuration
package com.example.jpa.Myconfiguration;
public class UserDetailsServiceImple implements UserDetailsService {
#Autowired
private UserRepository userRepository;
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// fetching data from DB
UserEntities userEntities = userRepository.getUserByUserName(username);
if (userEntities == null) {
throw new UsernameNotFoundException("Could not found user !!!");
}
CustomUserDetails customUserDetails = new CustomUserDetails(userEntities);
return customUserDetails;
}
}
package com.example.jpa.Myconfiguration;
public class CustomUserDetails implements UserDetails {
private UserEntities userEntities;
public CustomUserDetails(UserEntities userEntities) {
super();
this.userEntities = userEntities;
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(userEntities.getRoll());
return List.of(simpleGrantedAuthority);
}
#Override
public String getPassword() {
return userEntities.getUserPass();
}
#Override
public String getUsername() {
return userEntities.getUserEmail();
}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
return true;
}
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public boolean isEnabled() {
return true;
}
}
Application property:-
#Database configuration
spring.datasource.url=jdbc:mysql://localhost:3306/smartcontact
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.NonRegisteringDriver
spring.jpa.properties.hibernate.dilact=org.hibernate.dialect.Mysql8Dialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.globally_quoted_identifiers=true
spring.servlet.multipart.enabled=true
spring.servlet.multipart.file-size-threshold=2KB
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB

I am using Spring Jpa Repository to perform all database operations. I don't know how to select a specific value from my table without using any query

My entity class is here:
public class ClientDetails {
public ClientDetails() {
super();
// TODO Auto-generated constructor stub
}
#Id
#GeneratedValue
#Column(name="serialno")
public int serialno;
#Column(name="gstnum")
public int GSTnum;
#Column(name="bunk_name")
public String bunk_name;
#Column(name="mobile_num")
public int mobile_num;
#Column(name="password")
public String password;
public int getSerialno() {
return serialno;
}
public void setSerialno(int serialno) {
this.serialno = serialno;
}
public int getGSTnum() {
return GSTnum;
}
public void setGSTnum(int gSTnum) {
GSTnum = gSTnum;
}
public String getBunk_name() {
return bunk_name;
}
public void setBunk_name(String bunk_name) {
this.bunk_name = bunk_name;
}
public int getMobile_num() {
return mobile_num;
}
public void setMobile_num(int mobile_num) {
this.mobile_num = mobile_num;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
I want to select gstnum from my table based on my bunk_name.I don't want any native query like i did for gstnum in my jpa repository.
SELECT gstnum from pbm.client_details where bunk_name = 'yoga';
MY JPA REPOSITORY is
public interface ClientDetailsRepository extends JpaRepository<ClientDetails,Integer> {
public static final String gst_num = "SELECT * FROM pbm.client_details;";
//public static final String login_access = "SELECT * FROM clien_details WHERE gstnum pbm.client_details;";
#Query(value = gst_num, nativeQuery = true)
List<ClientDetails> getGstnum();
}
You could use the #Query but Spring Data would result not having too
#Query("SELECT GSTnum FROM ClientDetails where bunk_name = :callMeSomething")
List<ClientDetails> getGstnum(#Param("callMeSomething") String callMeSomething);
How a look here JPA Docs

Spring mongo repository sort descending by a certain property

I want to sort Descending by lastChange property, the List of items from mongo.
RequestRepository interface:
public interface RequestRepository extends MongoRepository<Request, String> {
List<Request> findByUser(String id);
}
Request.java:
#Document(collection = "Requests")
public class Request {
#Id
private String id;
private String user;
private String username;
private String requestTitle;
private String requestMessage;
private boolean read;
private Date lastChange;
private Date requestDate;
private boolean isActiveRequest;
private boolean isPremiumRequest; //paid request
public Request() {}
public Request(
String user,
String requestTitle,
String requestMessage,
boolean read,
Date lastChange,
Date requestDate,
boolean isActiveRequest) {
this.user = user;
this.requestTitle = requestTitle;
this.requestMessage = requestMessage;
this.read = read;
this.lastChange = lastChange;
this.requestDate = requestDate;
this.isActiveRequest = isActiveRequest;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getRequestTitle() {
return requestTitle;
}
public void setRequestTitle(String requestTitle) {
this.requestTitle = requestTitle;
}
public String getRequestMessage() {
return requestMessage;
}
public void setRequestMessage(String requestMessage) {
this.requestMessage = requestMessage;
}
public boolean isRead() {
return read;
}
public void setRead(boolean read) {
this.read = read;
}
public Date getLastChange() {
return lastChange;
}
public void setLastChange(Date lastChange) {
this.lastChange = lastChange;
}
public Date getRequestDate() {
return requestDate;
}
public void setRequestDate(Date requestDate) {
this.requestDate = requestDate;
}
public boolean isActiveRequest() {
return isActiveRequest;
}
public void setActiveRequest(boolean activeRequest) {
isActiveRequest = activeRequest;
}
public boolean isPremiumRequest() {
return isPremiumRequest;
}
public void setPremiumRequest(boolean premiumRequest) {
isPremiumRequest = premiumRequest;
}
}
In my code I have the following list:
List<Request> = RequestRepository.findByUser(userObj.getId());
I want to have the data from RequestRepository.findByUser(userObj.getId()); sorted DESCENDING by the property lastChange.
I have searched on StackOverflow, and found the following method to sort:
List<Request> findAllByOrderByUpdatedAtDesc();
but this does not work if I search by User.
What is the solution to search by User id and to sort by lastChange?
Thank you!
This should do it.
List<Request> findByUserOrderByLastChangeDesc(String user);
Update your question with proper details.

Spring Data Jpa Test returns null list even after child is saved

#Test
public void testAddPlayerToGame() {
gameRepository.save(createTestGame());
Game game = gameRepository.findOne(1l);
assertTrue(game.getId() > 0);
Player p = new Player();
p.setName("test 1");
p.setGame(game);
p.setChips(5000);
assertTrue(p.getId() == null);
playerRepository.saveAndFlush(p);
assertTrue(p.getId() != null);
flushAndClear();
Game game2 = gameRepository.findOne(1l);
assertEquals(1, game2.getPlayers().size());
}
The above test fails because game2.getPlayers() returns null.
Already went through JpaRepository caches newly created object. How to refresh it? but couldn't figure out how to solve.
The method flushAndClear used in the above code is blank, as follows :
protected void flushAndClear() {
// sessionFactory.getCurrentSession().flush();
// sessionFactory.getCurrentSession().clear();
}
Any help is really appreciated.
Update
Game & Player mapping code :
#Entity
#Table(name="game")
public class Game implements Serializable {
private static final long serialVersionUID = -495064662454346171L;
private long id;
private int playersRemaining;
private Player playerInBTN;
private GameType gameType;
private String name;
private boolean isStarted;
private Set<Player> players;
private HandEntity currentHand;
private GameStructure gameStructure;
#Column(name="game_id")
#Id
#GeneratedValue(strategy=GenerationType.TABLE)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
#Column(name="players_left")
public int getPlayersRemaining() {
return playersRemaining;
}
public void setPlayersRemaining(int playersRemaining) {
this.playersRemaining = playersRemaining;
}
#OneToOne
#JoinColumn(name="btn_player_id")
public Player getPlayerInBTN(){
return playerInBTN;
}
public void setPlayerInBTN(Player playerInBTN){
this.playerInBTN = playerInBTN;
}
#Column(name="game_type")
#Enumerated(EnumType.STRING)
public GameType getGameType() {
return gameType;
}
public void setGameType(GameType gameType) {
this.gameType = gameType;
}
#OneToMany(mappedBy="game", fetch=FetchType.LAZY)
public Set<Player> getPlayers() {
return players;
}
public void setPlayers(Set<Player> players) {
this.players = players;
}
#Column(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Column(name="is_started")
public boolean isStarted() {
return isStarted;
}
public void setStarted(boolean isStarted) {
this.isStarted = isStarted;
}
#OneToOne(fetch=FetchType.EAGER)
#JoinColumn(name="current_hand_id")
public HandEntity getCurrentHand() {
return currentHand;
}
public void setCurrentHand(HandEntity currentHand) {
this.currentHand = currentHand;
}
#OneToOne(fetch=FetchType.EAGER, cascade={CascadeType.ALL})
#JoinColumn(name="game_structure_id")
public GameStructure getGameStructure() {
return gameStructure;
}
public void setGameStructure(GameStructure gameStructure) {
this.gameStructure = gameStructure;
}
}
#Entity
#Table(name="player")
public class Player implements Comparable<Player>, Serializable{
private static final long serialVersionUID = -1384636077333014255L;
private String id;
private Game game;
private String name;
private int chips;
private int gamePosition;
private int finishPosition;
private boolean sittingOut;
#JsonIgnore
#Column(name="player_id")
#Id
#GeneratedValue(generator = "system-uuid")
#GenericGenerator(name = "system-uuid", strategy = "uuid2")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#JsonIgnore
#ManyToOne
#JoinColumn(name="game_id")
public Game getGame() {
return game;
}
public void setGame(Game game) {
this.game = game;
}
#Column(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Column(name="chips")
public int getChips() {
return chips;
}
public void setChips(int chips) {
this.chips = chips;
}
#Column(name="game_position")
public int getGamePosition() {
return gamePosition;
}
public void setGamePosition(int gamePosition) {
this.gamePosition = gamePosition;
}
#Column(name="finished_place")
public int getFinishPosition() {
return finishPosition;
}
public void setFinishPosition(int finishPosition) {
this.finishPosition = finishPosition;
}
#Column(name="sitting_out")
public boolean isSittingOut() {
return sittingOut;
}
public void setSittingOut(boolean sittingOut) {
this.sittingOut = sittingOut;
}
#Override
public boolean equals(Object o){
if(o == null || !(o instanceof Player)){
return false;
}
Player p = (Player) o;
if(this.getId() == null){
return this.getName().equals(p.getName());
}
return this.getId().equals(p.getId());
}
#Override
public int hashCode(){
if(id == null){
return name.hashCode();
}
return id.hashCode();
}
#Override
#Transient
public int compareTo(Player p){
return this.getGamePosition() - p.getGamePosition();
}
}
I am using HSQL db in the testing environment. Following is the configuration :
#Configuration
#EnableJpaRepositories(basePackages = "com.nitinsurana.repos")
#EnableTransactionManagement
class TestDataConfig {
#Bean(name = "transactionManager")
#Autowired
public PlatformTransactionManager getTransactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
jpaTransactionManager.setEntityManagerFactory(entityManagerFactory);
return jpaTransactionManager;
}
#Bean
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan("com.nitinsurana.domain");
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
em.setJpaProperties(getHibernateProperties());
em.afterPropertiesSet();
return em.getObject();
}
// #Bean
// public EntityManager entityManager(HibernateEntityManagerFactory entityManagerFactory) {
// HibernateEntityManager entityManager = (HibernateEntityManager) entityManagerFactory.createEntityManager();
// entityManager.setFlushMode(FlushModeType.AUTO FlushMode.ALWAYS);
// return entityManager;
// }
private Properties getHibernateProperties() {
Properties prop = new Properties();
prop.put("hibernate.show_sql", "false");
prop.put("hibernate.hbm2ddl.auto", "create");
prop.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
return prop;
}
#Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.HSQL)
// .addScript("classpath:com/bank/config/sql/schema.sql")
// .addScript("classpath:com/bank/config/sql/test-data.sql")
.build();
}
}
You need to write a FlushAndClear method that works. If not game2 gets not loaded for the database but from the internal cache. And if it is not loaded then the releationship become not updated.
class TestXXX {
#PersistenceContext
private EntityManager em.
private flushAndClear() {
em.flush();
em.clear();
}
}

Cannot delete entity (JPA & Spring)

What ever I try, I cannot delete a user entity when I call delete() from my userService class. I get an exception java.lang.IllegalArgumentException: Entity must be managed to call remove: com.blackbox.genesis.entities.User#30168a, try merging the detached and try the remove again. I'm obviously doing something wrong - despite merging, but I can't see what. Everything else works fine - I can create and update user entities without any problem.
Regards
My entity class;
#Entity
#Table(uniqueConstraints = {#UniqueConstraint(columnNames = "EMAIL")})
public class User implements Serializable {
#Id
#Column(name="username", length=50)
private String username;
#OneToOne(cascade = {CascadeType.ALL})
private Password password;
private boolean enabled;
private int serial;
private String email;
#Version
private int version;
#ElementCollection(targetClass=Authority.class)
#CollectionTable(name="USER_AUTHORITY")
private List<Authority> authorities;
#OneToMany(mappedBy="user", fetch=FetchType.LAZY, cascade=CascadeType.ALL, ``orphanRemoval=true)
private Set<License> licenses;
private static final long serialVersionUID = 1L;
public User() {
super();
this.authorities = new ArrayList<Authority>();
}
.... getters/setters.
My DAO class;
#Repository
public class UserJpaController {
#PersistenceContext
EntityManager em;
protected static final Logger logger = Logger.getLogger("com.blackbox.genesisng.entities.UsersJpaController");
public void create(User user) throws PreexistingEntityException, Exception {
if (findUser(user.getUsername()) != null) {
throw new PreexistingEntityException("Users " + user + " already exists.");
}
em.persist(user);
em.flush();
}
public void edit(User user) throws NonexistentEntityException, Exception {
user = em.merge(user);
em.flush();
}
public void destroy(String id) throws NonexistentEntityException {
User user = em.find(User.class, id);
user = em.merge(user);
em.remove(user);
}
public List<User> findUserEntities() {
return findUserEntities(true, -1, -1);
}
public List<User> findUserEntities(int maxResults, int firstResult) {
return findUserEntities(false, maxResults, firstResult);
}
private List<User> findUserEntities(boolean all, int maxResults, int firstResult) {
Query q = em.createQuery("select object(o) from User as o");
if (!all) {
q.setMaxResults(maxResults);
q.setFirstResult(firstResult);
}
return q.getResultList();
}
public User findUser(String id) {
return em.find(User.class, id);
}
public int getUserCount() {
Query q = em.createQuery("select count(o) from User as o");
return ((Long) q.getSingleResult()).intValue();
}
public User findUserByEmail(String email) {
Query q = em.createQuery("select Object(o) from User as o where o.email = :email");
q.setParameter("email", email);
List list = q.getResultList();
if (list.size() == 0) {
return null;
}
return (User) list.get(0);
}
public boolean exists(String id) {
try {
em.getReference(User.class,id);
return true;
}
catch (EntityNotFoundException e) {
return false;
}
}
}
and finally, the relevant portion of my service class
#Service
public class UserService {
#Autowired
UserJpaController dao;
#Autowired
LicenseJpaController licenseDao;
#Transactional
public void delete(UserDTO userDTO) {
if (exists(userDTO.getUserName())){
try {
dao.destroy(userDTO.getUserName());
} catch (NonexistentEntityException e) {
// ignore as the previous test should prevent this.
}
}
}
So sorry, but I'm an idiot! I was not calling the service class that I thought I was. Fixed that and everything works as expected. Once again, sorry folks.
Regards
Remove the
user = em.merge(user);
statement in your DAO destroy method. I am not sure if it causes the probem, but it is not needed because the user is loaded in the statement before.

Resources