Scenario :
I have 3 tables, Offer, Channel and Offer_Channels.
Basically Channel is a lookup table, i.e, the values in that table can neither be inserted nor updated by the application. An offer can contain one or many channels. I use the Channel table values to populate dynamic checkboxes. Anyways, so here is what I have :
@Entity
@Table(name = "OFFER")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Offer implements Serializable {
// Offer Id
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "offer_seq_gen")
@Column(name = "OFFER_ID")
private long OfferId;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "OFFER_CHANNELS", joinColumns = { @JoinColumn(name = "OFFER_ID") }, inverseJoinColumns = { @JoinColumn(name = "CHANNEL_ID") })
private Set<Channel> channels = new HashSet<Channel>();
//Other fields and corresponding getters and setters
}
Here is the Channel entity :
@Entity
@Table(name = "CHANNEL")
public class Channel implements Serializable {
private static final long serialVersionUID = 1L;
@NotNull
@Id
@Column(name = "CHANNEL_ID", insertable=false, updatable=false)
private Long channelId;
@Column(name = "CHANNEL_NAME", insertable=false, updatable=false)
private String channelName;
//getters and setters
}
Now, when a user creates an offer, I need to insert row in Offer table and Offer_Channels tables and do nothing(No updates/inserts) for Channel table. Initially, all three would happen, so to achive the "do nothing to Channel table" part, I put insertable=false and updateable=false on the Channel table columns and that worked like a charm. Now I used plain Hibernates for this. I mean I wrote a standalone java application and a main class to add an offer useing hibernate's session.save(offer). It ran the following queries :
Hibernate: insert into OFFER
Hibernate: insert into OFFER_CHANNELS
Alright, now, I have a rest service where I am using the Spring's JPA repository to save the information and I have the same domain objects setup. Now, when I add an offer, it runs :
Hibernate: insert into OFFER
Hibernate: insert into CHANNEL ( It is failing here obviously. I don't want this step to happen)
My question :
1. Why is it is trying to write something to Channel table even though I gave insertable=false in its domain object, and this is only happening with the Spring JPA setup. With the hibernate setup it just works fine.
3. Doesn't @JoinTable/ @OneToMany / insertable / updateble , go well with Spring JPA repository ?
What am I missing here ?
UPDATE :
@Service
@Transactional
public class OfferService {
@Inject
private OfferRepository offerRepository;
public Offer saveOfferInformation(Offer offer) {
log.debug("Saving Offer Info..");
log.debug("Offer object :"+offer);
return offerRepository.save(offer);
}
}
Repo :
public interface OfferRepository extends JpaRepository<Offer, Long> {
List<Offer> findByBuySku(String buySku);
}
And in the REST service Im just injecting the service and calling it, so no business logic in the REST service. Right now Im getting and the reason is it is trying to insert record to Channel table:
exception: "org.springframework.dao.DataIntegrityViolationException"
message: "could not execute statement; SQL [n/a]; constraint [PVS_OWNER.CHANNEL_PK]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement"
See Question&Answers more detail:
os