Updating multiple tables when saving entity Spring MVC Angular - angularjs

I have a problem with saving entity with references to database using
Spring MVC and AngularJS.
My entities:
Entity
#Table(name = "comment")
public class Comment {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name = "id", nullable = false)
private Long id;
#Column(name = "creation_date", nullable = false)
private Date creationDate;
#Column(name = "comment", nullable = false)
private String comment;
#ManyToOne
#JoinColumn(name = "article", nullable = false)
private Article article;
#ManyToOne
#JoinColumn(name = "user", nullable = false)
private User user;
}
#Entity
#Table(name = "article")
public class Article {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id", nullable = false)
private Long id;
#ManyToOne
#JoinColumn(name="user", nullable=false)
private User user;
...
}
How can I save new Article but at the same time add new entity to Comment table?
How can two updates be performed in one transaction?
How sholud I connect request from angular with controller, and how sholud they look?
Angular:
$http({
url : ..../new,
method : POST,
data : ?
})
#RestController
#RequestMapping(value = "/new", method = RequestMethod.POST)
public Article addArticle(#RequestBody Article article, ?) {
article.setId(null);
return articleService.save(article);
//but how to save comment?
}
Thank You!

Related

Spring JPA fetch nested entities

I have 3 entity classes with relations as below:
class SocietyData {
#OneToMany(mappedBy = "societyData")
private List<SubsectionData> subsectionDataList = new ArrayList<>();
}
class SubsectionData {
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "society_id", nullable = false)
private SocietyData societyData;
#OneToMany(mappedBy = "subsectionData")
private List<BasementData> basementDataList = new ArrayList<>();
}
class BasementData {
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "subsection_id", nullable = false)
private SubsectionData subsectionData;
}
I am trying to fetch society data information by using entity graph:
#Repository
public interface SocietyRepo extends JpaRepository<SocietyData, Long> {
#EntityGraph(attributePaths = {"subsectionDataList", "subsectionDataList.basementDataList"})
Optional<SocietyData> findById(long id);
}
I am not getting proper society data object and getting cant parse json exception after taking so long time sometimes!
How to solve this?
Thanks in Advance.

Hibernate: ManyToOne generating field raw(255)

I recently upgraded from hibernate-core 4.1.7 to 5.0.9 and Have problem with this code:
#ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
#JoinColumn(name = "FK_AAA", foreignKey = #ForeignKey(name = "CS_BBB"))
#org.hibernate.annotations.Index(name = "IDX_CCC", columnNames = "FK_DDD")
private ImportData importData;
This generate correct foreign columns pointing to the defining class, but also generating a column on the same class:
IMPORTDATA RAW(255)
Why is this raw(255) column generated ? I think it was not generated with Hibernate-core 4.1.7
any idea ?
Update 1: here is longer code fragments:
#MappedSuperclass
#Access(AccessType.PROPERTY)
public abstract class BaseEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
public abstract Long getId();
}
#Entity
#Table(name = "IMPORT_DATA", uniqueConstraints = {
#UniqueConstraint(name = "UC_IMP_BID", columnNames = {"BUSINESS_ID"})
}, indexes = {
#Index(name = "IDX_IMP_DGXML_ID", columnList = "FK_DGXML_ID"),
#Index(name = "IDX_IMP_IMPXML_ID", columnList = "FK_IMPXML_ID")
})
public class ImportData extends BaseEntity {
#Id #GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() { return id; }
// ...
}
#Entity(name = "MUTATION")
#Table(name = "MUTATION")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "TYPE", discriminatorType = DiscriminatorType.STRING)
#SequenceGenerator(name = "mutationsSeq", sequenceName = "MUTATIONS_SEQUENCE", allocationSize = 1)
public abstract class Mutation extends BaseEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = "mutationsSeq")
private Long id;
#ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
#JoinColumn(name = "FK_IMP_ID", foreignKey = #ForeignKey(name = "CS_MUT_IMP_ID"))
#org.hibernate.annotations.Index(name = "IDX_MUT_IMP_ID", columnNames = "FK_IMP_ID")
protected ImportData importData;
}
#Entity(name="XXX")
#DiscriminatorValue("XXX_DISC")
public class XXX extends Mutation {
// ...
}
I found an answer on Mapping composite key with Hibernate produces a raw field in Oracle:
I was mixing annotations on fields and methods. I also had #Id on an abstract superclass, and a redefinition on a derived class.
Fixing theses two elements, cleaning DB and regenerating in "create" ddl mode proved that the fix was no longer generating RAW field type.
Thanks for all your helps!

Hibernate cascade parent child when using sql server spatial dialect

I am using spring boot data jpa with SQLServer and spatial dialect as below:
spring.jpa.properties.hibernate.dialect=org.hibernate.spatial.dialect.sqlserver.SqlServer2008SpatialDialect
Parent Class:
#Entity
#Table(name = "users", schema = "dbo")
public class User {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
#ManyToMany(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
#JoinTable(name = "users_roles",
joinColumns = #JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "role_id", referencedColumnName = "id"))
private Collection<Role> roles = new ArrayList<>();
}
Child Class:
#Entity
#Table(name = "roles", schema = "dbo")
public class Role {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
#ManyToMany(mappedBy="roles", cascade = {CascadeType.ALL})
private Collection<User> users = new ArrayList<>();
}
on saving user:
u.setRoles(roles);
userRepository.save(u);
but alyways get user_id equals zero on table users_roles
please help
Note that SpatialDialect is needed to manage spatial data on other entities.

Collection null in AngularJS + Spring Data JPA #OneToMany #ManyToOne

I have a bidirectional relationship.
This is my entity factura:
#Entity
#Table(name = "T_FACTURA")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Factura implements Serializable {
...
#OneToMany(mappedBy = "factura")
#JsonIgnore
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Facturaservicio> facturaservicios = new HashSet<>();
...
#Override
public String toString() {
//all attributes except facturaservicios
}
}
This is my entity facturaservicio:
#Entity
#Table(name = "T_FACTURASERVICIO")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Facturaservicio implements Serializable {
...
#ManyToOne
private Factura factura;
...
#Override
public String toString() {
//all attributes except factura
}
}
This is my REST controller
#RestController
#RequestMapping("/app")
public class FacturaResource {
private final Logger log = LoggerFactory.getLogger(FacturaResource.class);
#Inject
private FacturaRepository facturaRepository;
#RequestMapping(value = "/rest/facturas",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public List<Factura> getAll() {
log.debug("REST request to get all Facturas");
return facturaRepository.findAll();
}
And this is my AngularJS controller:
$http.get('app/rest/facturas').
success(function (data, status, headers, config) {
console.log(JSON.stringify(data));
});
Why my collection is null in the AngularJS controller? How can I access to collection?
When JHipster creates a entity with OneToMany - ManyToOne relationship makes that the first entity (factura) has a list of the second entity (facturaservicios) but it not say the type of relation.
So the solution is add fetch = FetchType.EAGER in the #OneToManyRelation.
#OneToMany(mappedBy = "factura", fetch = FetchType.EAGER)
#JsonIgnore
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Facturaservicio> facturaservicios = new HashSet<>();
#ManyToOne
private Factura factura;
In the Factura entity, you need to remove the #JsonIgnore property in the following snippet:
#OneToMany(mappedBy = "factura")
#JsonIgnore
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Facturaservicio> facturaservicios = new HashSet<>();

hibernate criteria if collection contains collection

I have a Priv class
#Entity
#Table(name = "PK_PRIVS", schema = "dbo")
public class Priv implements java.io.Serializable{
private static final long serialVersionUID = 1L;
private String code;
private String name;
private String description;
private PrivType type;
//...
}
and a Report class which has many to many relation with Priv and contains Set of associated Privs - privs.
#Entity
#Table(name = "REPORT", schema = "dbo")
public class Report implements java.io.Serializable {
//...
private Set<Priv> privs = new HashSet<Priv>(0);
//...
#JsonIgnore
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "REPORT_PK_PRIVS", schema = "dbo", joinColumns = { #JoinColumn(name = "REPORT_ID") }, inverseJoinColumns = { #JoinColumn(name = "PK_PRIVS_CODE") })
public Set<Priv> getPrivs() {
return this.privs;
}
public void setPrivs(Set<Priv> privs) {
this.privs = privs;
}
}
Now I have a Set of Strings, which are codes of Priv classes (code is Primary Key in Priv).
Set<String> privsCodesSet; //set of codes of Priv classes
I need a criterion which allow me to find that Reports, which all codes from its Priv set contains in privsCodesSet. For example if I have privsCodeSet = {"code1", "code2"}
Report with privs with codes {"code1"" should be in result, but
Report with privs with codes {"code1", "code2", "code3"} should not.
I also have class which is join of Priv and Report, but I'm not sure if it's help.
This code should work
Criteria reportPrivCriteria = currentSession()
.createCriteria( Report.class, "r");
reportPrivCriteria.createAlias("privs", "p");
reportPrivCriteria.add(Restrictions.in(p.code, privsCodeSet));
Do you have something like this on your Priv class?
private Set<Report> reports;
// ...
#ManyToMany(mappedBy="privs")
public Collection<Report> getReports() {
return reports;
}

Resources