Id сущности

 
 
 
Сообщения:187
Есть сущность.
@Entity
@Table(name = "baskets")
public class Basket {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private long id;
	@ElementCollection
	@CollectionTable(name = "basket_products")
	@MapKeyJoinColumn(name="product_id")
	@MapKeyColumn(name = "product_id")
	@Column(name = "amount")
	private Map<Product, Double> products;
	@NotNull
	@ManyToOne
	@JoinColumn(name="username")
	private User user;
	@NotNull
	private LocalDateTime date;
	
	public Basket() {
		this.date=LocalDateTime.now();
		this.products = new HashMap<Product, Double>();
		System.out.println("ID"+this.id);
	}

	public long getId() {
		return id;
	}

	public Map<Product, Double> getProducts() {
		return products;
	}

	public void setProducts(Map<Product, Double> products) {
		this.products = products;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public LocalDateTime getDate() {
		return date;
	}

	public void setDate(LocalDateTime date) {
		this.date = date;
			
	}
	
	public boolean containsProduct(long id) {
		for (Map.Entry<Product,Double> entry : this.getProducts().entrySet()) {
			if (entry.getKey().getId()==id) return true;
		}

		return false;
	}
	
	public boolean contains(String name) {
		for (Map.Entry<Product,Double> entry : this.getProducts().entrySet()) {
			if (entry.getKey().getName().equals(name)) return true;
		}

		return false;
	}
	
	public Product findByName(String name) {
		for (Map.Entry<Product,Double> entry : this.getProducts().entrySet()) {
			if (entry.getKey().getName().equals(name)) {
				return entry.getKey();
			}
		}
		return null;

	}
	
	public void removeProduct(String name) {
		this.products.remove(this.findByName(name));
	}
	
	@Override
	public String toString() {
		StringBuilder prod = new StringBuilder();
		for (Map.Entry<Product, Double> entry : this.products.entrySet())
				{
				    prod.append(entry.getKey()).append(" ").append(entry.getValue());
				}
		
		return prod.toString();
	}
	
	

}

Когда она создается оператором new, она уже имеет id = 0.
Это правильное поведение? После вызова функций save или persist, ее id так и не меняется.
 
 
Сообщения:573
vallball:
Это правильное поведение?

Правильное. Примитивный тип long инициализируется нулем. Если хотите чтобы был null, то сделайте id объетной оберткой типа Long.
 
 
Сообщения:187
А почему после save() или persist() id сущности не меняется?
 
 
Сообщения:573
Ну так потому и не меняется, что уже задано значение. Ноль это тоже вполне допустимое значение.
 
 
Сообщения:187
А если я хочу, чтобы эта сущность была сохранена в базе данных, как это сделать?
Обычно сущности создаются без id? И получают его из базы данных при переводе в состояние persist?
 
 
Сообщения:573
vallball:
Обычно сущности создаются без id? И получают его из базы данных при переводе в состояние persist?

Да. Обычно это так.
Если Вы хотите что бы id сущности генерировался JPA, надо в качестве id использовать nullable типы, т.е. не примитивы.
 
 
Сообщения:9895
Если использовать hbm.xml для маппинга, то там у ID есть атрибут unsaved-value, его можно было бы установить в 0. В аннотации она так и не попала. Так что с аннотациями единственный выход - использовать Long вместо long.
Изменен:20 мар 2019 09:50
 
 
Сообщения:187
Спасибо за объяснение.
В этом же проекте есть сущность Product. Там после сохранения экземпляра в базу он получает id, совпадающий с тем, что есть в базе. Тип id - примитивный long. Это как можно объяснить?
@PostMapping("/addProduct")
    public String create(@ModelAttribute("product") Product product, @ModelAttribute("quantity") Quantity quantity){
		productService.save(product);
		quantityService.save(quantity);
		System.out.println("ИД нового товара " + product.getId());
		return "redirect:/";
    }
 
 
Сообщения:9895
У Product'a ID наверно проставлен когда тот приходит в метод create(), соответственно ему никто ему ID не назначает - он изначально есть. Ну и в итоге происходит update вместо insert. Если бы произошел insert, то ты получил бы ошибку от БД что запись с таким ID уже существует.
Изменен:21 мар 2019 05:31
 
 
Сообщения:187
Вот смотрите - изменил метод, чтобы он показывал, как меняется ID:
@PostMapping("/addProduct")
    public String create(@ModelAttribute("product") Product product, @ModelAttribute("quantity") Quantity quantity){
		System.out.println("ИД нового товара до вызова БД " + product.getId());
		productService.save(product);
		quantityService.save(quantity);
		System.out.println("ИД нового товара " + product.getId());
		return "redirect:/";
    }

И вот что появилось в консоли:
ИД нового товара до вызова БД 0
Hibernate: insert into products (name, price) values (?, ?)
Hibernate: insert into quantities (amount, product_id) values (?, ?)
ИД нового товара 16


Сам продукт создается так:
@ModelAttribute("product")
	public Product newProduct() {
		return new Product();
		
	}


А ещё, подскажите, для обновления полей persistent объекта нужно использовать session.flush()? У меня применяется session.update().
Изменен:21 мар 2019 06:27
 
 
Сообщения:9895
vallball:
ИД нового товара 16
Ну еще раз - если товар с такой ID и вправду существует, то мы должны получить ошибку от БД че-то вроде unique constraint violation.
vallball:
А ещё, подскажите, для обновления полей persistent объекта нужно использовать session.flush()? У меня применяется session.update().
Если FlushMode=AUTO (умолчание), то ничего делать не надо, Hibernate сам во время коммита (или перед следующим select'ом) сделает UPDATE. Когда он получает объект из БД, он сохраняет изначальные значения полей. Перед коммитом он проверит что изначальные поля совпадают с текущим состоянием объекта, и если нет - делает UPDATE/DELETE.
Изменен:21 мар 2019 11:56
 
 
Сообщения:187
Староверъ:
У Product'a ID наверно проставлен когда тот приходит в метод create(), соответственно ему никто ему ID не назначает - он изначально есть.

Староверъ:
Ну еще раз - если товар с такой ID и вправду существует, то мы должны получить ошибку от БД че-то вроде unique constraint violation.

Сущность Product c примитивным long ID после сохранения в базу данных этот ID меняет на тот, что ему назначает база данных.
Но сущность Basket того же самого не делает. И я не могу понять, почему.
 
Модераторы:Нет
Сейчас эту тему просматривают:Нет