I have nested models in a very simple Play application. I have a User model which looks like;
#Entity
public class User extends Model {
#Id
public Integer id;
#Constraints.Email
#Constraints.Required
public String email;
#Constraints.Required
private String password;
#ManyToOne
public City city;
}
And the City model looks like;
#Entity
public class City extends Model {
#Id
public Integer id;
public String name;
#ManyToOne
public Country country;
}
Which is again, very simple.
I then have the Country model, which is;
#Entity
public class Country extends Model {
#Id
public Integer id;
public String name;
}
Now, what I'm doing is POST-ing parameters email, password, and city_id to an action;
public static Result registerUser() {
Form<Register> registerForm = form(Register.class).bindFromRequest();
Logger.debug(registerForm.toString());
if (registerForm.hasErrors()) {
return badRequest(register.render(registerForm));
} else {
User user = form(User.class).bindFromRequest().get();
user.save();
return redirect(controllers.routes.Application.login());
}
}
The database I'm using is MySQL, and I can see the new User rows coming in. What I always see is that city_id stays null which wasn't what I had assumed.
I had assumed Hibernate to take care of the relationship between the objects and the corresponding database foreign keys, but that doesn't seem to be working.
I have a city with id = 1 entered into the city table already and that is the city_id I'm sending through POST.
What's going on here?
Related
I have user in database and trip holidays, now, I want to create a document that will store holidays that user saved. Something like when you go on some website for buying products and then you 'favorite - save - bookmark' something.
I have a couple of entities for trip holidays like AdventureHolidays, Backpacking, CruiseHolidays etc.
Model looks like this:
#Document("adventureholidays")
public class AdventureHolidays {
#Id
private String id;
private String title;
private String description;
private String state;
private String typeOfAdventureHolidays;
private String image;
And I have a lot of them for each holiday as I said, Backpacking, CruiseHolidays etc.
I have user model like this:
#Document
public class User {
#Id
private String id;
#Indexed(unique = true)
#NonNull
private String username;
#Indexed(unique = true)
#NonNull
private String email;
#JsonIgnore
#NonNull
private String password;
Next I created a new model that will actually store userId and documents that he has saved.
#Document
public class UserSavedTrips {
#Id
private String userId;
#DBRef
AdventureHolidays adventureHolidays;
#DBRef
User user;
I dont know did I even implement that document for storing user saved holidays right.
Next I created repository:
#Repository
public interface UserSavedTripsRepository extends MongoRepository<UserSavedTrips, String> {
}
And service:
#Service
public class UserSavedTripsServiceImpl implements UserSavedTripsService {
#Autowired
UserSavedTripsRepository userSavedTripsRepository;
#Override
public UserSavedTrips save(UserSavedTrips userSavedTrips) {
return userSavedTripsRepository.save(userSavedTrips);
}
}
How I can now create controller for this so actually I can do what I want when I hit save button? And also, is this even good? Will that actually save holidayID to userSavedHolidays with also userID?
I use Objectify in AppEngine with JAva. I would like to model a many-many relationship in which the resolution entity has additional fields, as below
#Entity
public class Account {
public #Id Long id;
public String name;
}
#Entity
public class Baby {
#Id public Long id;
public String name;
}
#Entity
public class AccountBaby {
public #Id Long id;
#Index
#ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
public Ref<Account> account;
#Index
#ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
public Ref<Baby> baby;
public int permission;
}
If I follow this model, I can not query list of account for given baby's id (or list of baby for given account's id) as the query below
List<AccountBaby> babies = OfyService.ofy().load().type(AccountBaby.class).filter("account=",
Key.create(Account.class, accountId)).list();
Is they any other way to query or model this relationship?
You need a space in "account =". Or you can just leave off the "=", which is implied.
What you're actually searching for is a property which is literally named "account=" (which can be saved in the datastore with the low level api). This is mentioned in the javadocs for the filter() method.
The following query throws the exception:
Query query = session.createQuery("from Associate as a order by a.username asc");
associates = query.list();
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [ca.mypkg.model.Associate#0]
If I create an entry in the database with id of 0 it works just fine. I don't really get it because I'm just trying to load all the entries in the db not just a specific one.
Similar questions I've found have been concerned with trying to load an object with a given ID I'm doing no such thing.
Associate class:
#Table(name = "user")
#XmlRootElement(name = "associate")
public class Associate implements Serializable {
private String username;
private String password;
private String firstName;
private String lastName;
private String userType;
private int id;
private String email;
private String isActive;
private Department dept;
private String lastUpdated;
private String associate_type;
// ...
#Id
#GeneratedValue
public int getId() {
return id;
}
#OneToOne
#JoinColumn(name = "dept")
public Department getDept() {
return dept;
}
From my experience this type of error message usually means it does not find joined entity by mentioned id, and not the entity requested in the query (Associate, in your case).
My guess is that Associate class contains a join entity which has primitive type primary key.
I have two classes: Furniture and Painting. Those are extending Item.
Item has the following code:
#Entity
public class Item implements Comparable, Serializable {
#Id #GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
#ManyToOne
private User seller;
#Embedded
#AttributeOverrides({
#AttributeOverride(name = "description",
column = #Column(name = "c_description"))})
private Category category;
private String description;
public Item() {
}
public Item(User seller, Category category, String description) {
this.seller = seller;
this.category = category;
this.description = description;
this.seller.addItem(this);
}
Painting has the following code:
#Entity
public class Painting extends Item {
private String title;
private String painter;
public Painting() {
}
public Painting(String title, String painter, User seller, Category category, String description) {
super(seller, category, description);
this.title = title;
this.painter = painter;
}
Furniture has the following code:
#Entity
public class Furniture extends Item {
private String material;
public Furniture() {
}
public Furniture(String material, User seller, Category category, String description) {
super(seller, category, description);
this.material = material;
}
Before, I tried some code persisting the Item objects. That worked fine.
Now I'm trying to persist a Painting-object, persisting it through an Entity Manager.
I get the following error:
Object: auction.domain.Furniture#5d3468fd is not a known entity type.
It seems like I forgot something or did something wrong, probably in the Painting-class. What could it be?
I forgot to update my Persistence Unit. After adding the Furniture and Painting classes, the information got in to the database. Above code is correct.
I am developing a Java Desktop Application and using JPA for persistence. I have a problem mentioned below:
I have two entities:
Country
City
Country has the following attribute:
CountryName (PK)
City has the following attribute:
CityName
Now as there can be two cities with same name in two different countries, the primaryKey for City table in the datbase is a composite primary key composed of CityName and CountryName.
Now my question is How to implement the primary key of the City as an Entity in Java
#Entity
public class Country implements Serializable {
private String countryName;
#Id
public String getCountryName() {
return this.countryName;
}
}
#Entity
public class City implements Serializable {
private CityPK cityPK;
private Country country;
#EmbeddedId
public CityPK getCityPK() {
return this.cityPK;
}
}
#Embeddable
public class CityPK implements Serializable {
public String cityName;
public String countryName;
}
Now as we know that the relationship from Country to City is OneToMany and to show this relationship in the above code, I have added a country variable in City class.
But then we have duplicate data(countryName) stored in two places in the City class' object: one in the country object and other in the cityPK object.
But on the other hand, both are necessary:
countryName in cityPK object is necessary because we implement composite primary keys in this way.
countryName in country object is necessary because it is the standard way of showing relashionship between objects.
How to get around this problem?
countryName in CityPK should be marked read-only using #Column(insertable = false, updatable = false) and both countryNames should be mapped to the same column (using name property):
#Entity
public class City implements Serializable {
#EmbeddedId
private CityPK cityPK;
#ManyToOne
#JoinColumn(name = "countryName")
private Country country;
}
#Embeddable
public class CityPK implements Serializable {
public String cityName;
#Column(name = "countryName", insertable = false, updatable = false)
public String countryName;
}
IMO the proper way to deal with such issues would be to use a generated internal (typically Long) ID instead of a natural primary key - this eliminates the whole problem. Of course, this requires a modification of your DB schema, but from your post I assume that this is possible.
#Entity
public class City implements Serializable {
private Long id;
private String name;
private Country country;
#Id
#GeneratedValue
#Column(name = "CITY_ID")
public Long getId() {
return this.id;
}
private void setId(Long id) {
this.id = id;
}
// more getters, setters and annotations
}