Как стать автором
Обновить
14
0

Пользователь

Отправить сообщение

Да, совершенно верно, я к сожалению упустил, что автор на open wp. Это, несомненно, облегчает ситуацию, но суть не меняется - foreign worker это определенный барьер и не все работодатели готовы через него перейти.
Мой поинт в том, что скорее всего улучшение резюме не поможет. Я бы посоветовал выбирать компании у которых есть история рабочих отношений с иностранными гражданами. И наверняка это будут компании побольше, маленькие не станут заморачиваться.

TLRD: скорее всего дело в сложности найма человека без PR/citizenship.
Я работаю в Канаде senior developer'ом. Попал я сюда сильно иначе, чем автор поста, но могу описать некторые нюансы местного трудоустройства, которые, возможно, объясняют ситуацию, в корой автор оказался.
Все очень сильно зависит от наличия PR (permanent residence). Насколько я могу судить из поста, у автора его нет, а есть только виза. Для потенциального работодателя процесс найма такого человека (даже если он прошел все интервью и всем понравился) выглядит следующим образом:
- оформление LMIA (labor market impact assessment). это такое разрешение, выданное провинцией на найм иностранного гражданина. В Онтарио, где автор судя по всему находится, компания может получить LMIA только если докажет, что в течение 3х месяцев искала местного на эту позицию и на нашла. Потом еще этот LMIA не быстро делается - пара месяцев запросто, тут никто не торопится.
- после LMIA надо получить еще work permit. это быстрее, чем LMIA, но всякое бывает.
- я почти уверен, что вся эта бюрократия для компании не бесплатна. как минимум нужен иммиграционный адвокат, который ведет все дела, пинает госучреждения, если заявка застряла - это вообще норма - и все такое прочее.
- дополнительно ко всему у foreign worker куча всяких прав, которые надо соблюдать, однажды наняв его.
Кстати в коментах еще было что-то про гражданство, типа Россия/Беларусь не берем. Так вот, это некоторое когнитивное искажение. Верите или нет, тут вообще всем пофиг, откуда вы.

Потому что у потенциальных инвесторов есть обоснованные сомнения в окупаемости таких инвестиции на территории РФ.
Предприятия производства микроэлектроники строятся 5-7 лет, на эти сроки нужен стабильный налоговый и таможенный режим, квалифицированный персонал, доступ к кредитам под низкий процент, возможность закупки оборудования со всего мира для твоего завода. А потом еще нужны рынки сбыта для продукции и гарантии права собственности.
Что мы имеем сегодня в России - налоговый режим не стабилен - хоть завтра к тебе могут прийти и уведомить что тебе надо заплатить windfall tax (или еще что-нибудь), оборудование из-за санкции в Россию везти как минимум дорого (как максимум - вообще не продадут), рабочая сила дорожает, доступ к международным рынкам капитала перекрыт (а в РФ ставка 15%. сегодня. а завтра 7. или 17?). Право собственности? Формальное - Данон и Балтика не дадут соврать. Рынок сбыта - в текущих условиях только РФ - а это очень маленький рынок, в лучшие годы 2% мирового ввп. Поэтому в крупную серию не выйти, а все остальное нерентабельно даже без всего вышеперечисленного. Можно ли на это все наплевать и построить завод? Да. Но с учетом всех заложенных рисков продукция его будет золотая, если он вообще когда-то будет построен. Вот и не инвестируют. Проще даже под санкциями через нескольких посредников провезти серую партию.

Небольшое уточнение: в java один public класс на один файл. Вдобавок к нему в этом же файле может быть сколько угодно классов с пакетной видимостью.
Исходник на github: HLS
Тот пример, который я привел, он для spring самый стандартный, проповедуется в литературе, соответствует разбиению логики приожения на уровни, о которых тут так много говорилось выше. Что каксается вашего подхода, то я не виду причин, почему его нельзя написать на spring (ну может там будет побольше кода и меньше спринговых плюшек).
Сделать время жизни сессии меньше времени жизни реквеста не было самоцелью и ничего специально для этого не делалось. Просто это вытекает из из того кода, который я привел. Прокомментирую:

@RequestMapping(value = "/{respType:customers|suppliers}", method = RequestMethod.GET)
public void getXML(@PathVariable String respType, Model model) {
// Грубо говоря, этот метод определяет собой границы жизни HttpServleеRequest/Response, вернее то 
// место, где мы можем до них добраться, сделав inject в один из параметров, например.
	String fetchProfile = ("customers".equals(respType)) ? "companyWithCustomers" : "companyWithSuppliers";
	model.addAttribute(
           // Тут сессии еще не было
           companyService.getCompany(fetchProfile)
           // А тут она уже все сделала и закрылась
        );
// Дальше Spring положит что надо в response и отправит его
}
Я его отбросил по той самой причине, на которую вы хотите забить. А так у меня к OpenSessionInView нет претензий.
Что касается сессии

@Service
public class CompanyService {	
	@Autowired
	private CompanyDAO companyDAO;
	
	@Transactional
	public Company getCompany(String fetchProfile) {
		return companyDAO.getCompany(fetchProfile);
	}
}

@Transactional с помощью spring AOP делает мне session.beginTransaction() и session.commit() и session.close(), так что по сути все тут. На вопрос, завязана ли в моей реализации сессия на scope HTTP request — ответ нет. С Hibernate я работаю на spring, а там таких реализаций мне видеть не довелось, если честно. У меня, как привило, время жизни сессии в 99% случаев меньше времени жизни HttpRequest

@Controller
@RequestMapping("rest/company")
public class CompanyController {	
	@Autowired
	private CompanyService companyService;
	
	@RequestMapping(value = "/{respType:customers|suppliers}", method = RequestMethod.GET)
	public void getData(@PathVariable String respType, Model model) {
		String fetchProfile = ("customers".equals(respType)) ? "companyWithCustomers" : "companyWithSuppliers";
		model.addAttribute(companyService.getCompany(fetchProfile));
	}
}
А в вашей аналогии что-то есть:)
И вам спасибо.
Ну вот опять мы приехали к частной spring'овой реализации. Да, вы правы, в случае spring так и будет — @service, @transactional, все дела. Мне было важно показать не где эти методы (и DTO) будут, а что они будут вообще и их число будет расти. Я прекраcно понял вашу позицию — вы сторонник классического разделения логики приложения по слоям и не терпите отступлений и экспериментов. Вы не пропускаете lazyinit выше service c помощью ResultTransformer'ов (или Dozer) и считаете, что это едиственно верно и подходит по концепции разбиения на уровни (domain, dao, service...). Но ведь это уровни созданы для вас, а не вы для уровней. Никто не заставляет обязательно следовать их букве и, если я вижу способ сократить объем кода но слегка нарушив концепции без видимых последствий, я его сокращу. И с этой точки зрения нет причин считать что Hibernate.isIniialized более или менее косячен, чем ResultTransformer — они решают одну и ту же проблему. Вопрос, который мы тут начали обсуждать, гораздо шире чем тема статьи. Это вопрос: творчество и малый объем кода vs. подходы, проверенные временем. Хотя, может и я однажды пойму, что в моей работе нет места для творчества и что все следует делать «как надо».
Чем хорош пример с AccessorFactory, это тем, что он замечательно сосуществует со стандартной концепцией и нет нужды чем-то жертвовать. От DTO никто не отказывается, я об этом в предыдущем комменте написал. Эх, вообще тяжело комментировать куски, вырванные из контекста…
Хочу сказать «спасибо» свом критикам, благодяря им я понял свою главную ошибку — не так преподнес статью. У читателей складывается впечатление, что я изобрел эту AccessorFactory, а на всем остальном (пункты 1-5) поставил крест. Конечно же, это не так. Все определяется конкретной ситуацией. В статье нарочно приведен пример, когда использование AccessorFactory оправдано.
Вот вы говорите: давайте сделаем 2 DTO: CompanyAndSuppliersDTO, CompanyAndCustomersDTO. Да давайте, я сам так неоднократно делал: получим помимо прочего 2 DTO + DAO c двумя методами (по одному на DTO). Если еще что-нибудь понадобится (к примеру, появятся новые ленивые колекции), надо будет добавлять новые DTO и методы соответственно.
С AccessorFactory: DAO (с одним методом) + сама AccessorFactory (неограниченно применяемая на все lazyinit-случаи, который в будущем могут возникнуть)
Можно возразить — а мне надо обязательно DTO, я там дополнительные вещи какие-то делаю. Пожалуйста, используйте DTO — оно прекрасно может жить совместно с этой AccessorFactory (она вообще совместима с любыми решениями 1-5), более того, пакет с DTO можно не маркировать @XmlAccessorFactory — и она не будет применяться.

Далее, хочу отметить, что я не зануляю поля у самой entity, я подсовываю сериализатору null вместо полей, которые мне не нравятся, тут все-таки есть разница. Ошибок не будет, если у сериализатора это поле не помечено required. Если помечено — нужно подсовывать что надо, для этого есть все возможности.

Ну и самый скользкий вопрос во всей статье, на который справедливо обращено внимание — я назвал DTO антипаттерном. Каюсь, погорячился. Вопрос «DTO — pattern or antipattern?» существует давно и, боюсь, не нам с вами на него ответить. Я воспринимаю DTO, как средство без которого иногода не обойтись, но с обоснованиями. В своем примере я не вижу причины, почему использование DTO явно выгодней, кроме того, что это стандартный способ к которому все привыкли.
По моему, вы чересчур сгущаете краски. AccessorFactory в пакекта model тоже быть не должно. Это что-то вроде util. Что касается coupling: во-первых, без coupling вообще ничего не работает, во-вторых: я не вижу ничего страшного в том, чтобы в класс, предназначенный для работы с lazyinit, сделать import (один-единственный, кстати) hibernate'ового класса (или static метода).
В целом, решение с AссessorFactory дает очень небольшой coupling: она вообще не в одном классе не прописана, все происходит совершенно прозрачно и определяется одной аннотацией на package уровне
Ваше решение это defacto DTO. Придется определять 2 класса для этих DTO, которые вы будете подсовывать ResultTransformer'у. Да можно, вариант. Но почему вы отказываете AccessorFactory быть вариантом? Тоже работает, код не портит. Сфера применения, как уже верно отмечено, одним lazyinit не ограничивается.
Это не костыль, а метод борьбы с ними.
Ну вот, мы и добрались до места, где участники дискуссии начинают говорить то, что они на самом деле думают о посте)
Еще раз повторюсь, если можно загрузить все данные, то того, как сериализатор их слопает — это хорошо, так и надо делать. Но судя по количеству вопросов в гугле типа «jaxb lazyinitialization что мне делать» — не всегда (или не у всех) это получается. Я вовсе не хочу, что бы предложенное мной решение тиражировалось на все возможные случаи. Но иногда оно может быть полезным и… более элегантным что ли, чем использование DTO, которое по вашему мнению я незаслуженно обидел.
Конечно, было бы круто отдавать сериализатору всякий раз то, что он может съесть. Более того, если такой способ существует — так и надо делать. Мне просто хотелось привести пример, когда пункты 1-5 из гугла не прокатывают или смотрятся не очень хорошо.
Да, насчет hithub была отличная мысль — hls github
Уважаемый, я с вами полностью согласен. Все в кучу на DAO-уровне мешать не следует. Только вот статью эту я написал не для демострации того, какие уровни можно сделать, а как заставить JAXB не сериализовать ленивые коллекции. Кусочек кода из DAO приведен только для того, чтобы было понятно — объект Company мы можем получать как с ленивой коллекцией customers, так и с ленивой коллекцией suppliers. Код для service-слоя и контроллеров просто не приведен, — он слишком spring-специфичный и к теме статьи не относится. Если же вас все таки интересует, как у меня сделано разнесение по слоям — скачайте исходник. Если не сможете, — залью на github, а то тут уже жаловались. Обсудим все ваши замечания.

Информация

В рейтинге
Не участвует
Откуда
Москва, Москва и Московская обл., Россия
Зарегистрирован
Активность