0

I'm using a test spring boot project to learn some hibernate. I have 2 interfaces extending CrudRepository - Address and Student both annotated with @Transactional and @Repository. Many students should share the same address.

@Transactional
@Repository
public interface AddressDao extends CrudRepository<Address, Integer> {}


@Entity
public class Address {

@Id
@GeneratedValue
private int addressId;
private String street;
private String city;
private String state;
private String zipcode;

etc.

@Entity
public class Student {

@Id
@GeneratedValue
private long studentId;

@Column(nullable = false, length = 70)
private String studentName;

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "studentAddress")
private Address studentAddress;

etc. and the main class:

@SpringBootApplication
public class MainSpringBootClass extends SpringBootServletInitializer implements CommandLineRunner {

@Autowired
StudentDao studentDao;

@Autowired
AddressDao addressDao;

public static void main(String[] args) {
    SpringApplication.run(MainSpringBootClass.class, args);
}


@Override
@Transactional
public void run(String... args) {

    List<Address> list = new ArrayList<>();
    addressDao.findAll().forEach(list::add);

    Address address;

    if (list.size() > 0) {
        address = list.get(0);
    } else {
        address = new Address().withCity("London").withZipcode("W1J 9LL")
                .withStreet("Piccadilly").withState("UK");
    }

    Student student1 = new Student().withName("Ann").withAddress(address);
    Student student2 = new Student().withName("James").withAddress(address);

    studentDao.save(student1);
    studentDao.save(student2);

    addressDao.delete(1);
    addressDao.findAll().forEach(System.out::println);
}

}

Problem is every time I run this code 2 new students are added and I don't see addressDao.delete(1) being executed, no exception is thrown, no log from hibernate is printed that it tries to delete the record. Also transaction is not rolled back. I can see both addressDao.delete(1) and exception if I remove (cascade = CascadeType.ALL) from Student.java but it also means I have to manually save address first before saving student. What do I do wrong?

Edit: I added Long removeByCity(String city); to my AddressDao and replaced addressDao.delete(1) with it. I see it returns 1 so looks like it gets executed but I still don't get any exception here. I'm getting exception only if I don't use save before.

Marty
  • 31
  • 4
  • can you share your implementation of AddressDao? – Junbang Huang May 05 '17 at 16:19
  • I edited the question. StudentDao looks the same except it uses Long, not Integer. – Marty May 05 '17 at 16:34
  • Do we really need `@Transactional` on the `run` mehod? – Master Po May 05 '17 at 17:16
  • are you sure you have an address with id 1? – Junbang Huang May 05 '17 at 17:20
  • @Pete maybe not. I wanted it to rollback automatically in case of error. JunbangHuang I'm sure. If started with an empty tables it will be created, then reused – Marty May 05 '17 at 17:26
  • try changing the following code. addressDao.delete(address.getId()); – Junbang Huang May 05 '17 at 17:31
  • no change. I still see: Hibernate: insert into student (student_address, student_name) values (?, ?) Hibernate: insert into student (student_address, student_name) values (?, ?) Hibernate: select address0_.address_id as address_1_0_, address0_.city as city2_0_, address0_.state as state3_0_, address0_.street as street4_0_, address0_.zipcode as zipcode5_0_ from address address0_ org.ms.hibernate.bo.Address@66f5a5f5 no attempt to delete – Marty May 05 '17 at 17:41
  • Might be because it is [re-persisted by a cascaded `PERSIST` operation](http://stackoverflow.com/questions/34840903/silently-ignored-remove). This [blog post](http://www.baeldung.com/delete-with-hibernate) might also be helpful. – Dragan Bozanovic May 05 '17 at 21:58
  • @DraganBozanovic Thank you, I see now un-scheduling entity deletion [[org.ms.hibernate.bo.Address#1]] in the logs. – Marty May 06 '17 at 12:45
  • do you have your getters and setters on each entity? If not, I believe that there is the problem. And also, as Junbang Huang said, could you share you DAO's and the CrudRepository please? Maybe there is also a problem there. – Nicolas Curat May 05 '17 at 16:37
  • yes, I have getters/setters, didn't include them for brevity. CrudRepository comes from org.springframework.data.repository. – Marty May 05 '17 at 16:42
  • Can i ask why you used "@Transactional" and "@Repository" in the address and student DAO instead of @RepositoryRestResource? Maybe by changing this the problem solves. – Nicolas Curat May 05 '17 at 16:53
  • I'm not useing rest here. Transactional comes from javax.transaction and Repository from spring – Marty May 05 '17 at 17:43
  • That would also mean that if I want to see my exception I'd need to delete in a different session. – Marty May 06 '17 at 14:17

0 Answers0